Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski: - fix failure to add bond interfaces to a bridge, the offload-handling code was too defensive there and recent refactoring unearthed that. Users complained (Ido) - fix unnecessarily reflecting ECN bits within TOS values / QoS marking in TCP ACK and reset packets (Wei) - fix a deadlock with bpf iterator. Hopefully we're in the clear on this front now... (Yonghong) - BPF fix for clobbering r2 in bpf_gen_ld_abs (Daniel) - fix AQL on mt76 devices with FW rate control and add a couple of AQL issues in mac80211 code (Felix) - fix authentication issue with mwifiex (Maximilian) - WiFi connectivity fix: revert IGTK support in ti/wlcore (Mauro) - fix exception handling for multipath routes via same device (David Ahern) - revert back to a BH spin lock flavor for nsid_lock: there are paths which do require the BH context protection (Taehee) - fix interrupt / queue / NAPI handling in the lantiq driver (Hauke) - fix ife module load deadlock (Cong) - make an adjustment to netlink reply message type for code added in this release (the sole change touching uAPI here) (Michal) - a number of fixes for small NXP and Microchip switches (Vladimir) [ Pull request acked by David: "you can expect more of this in the future as I try to delegate more things to Jakub" ] * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (167 commits) net: mscc: ocelot: fix some key offsets for IP4_TCP_UDP VCAP IS2 entries net: dsa: seville: fix some key offsets for IP4_TCP_UDP VCAP IS2 entries net: dsa: felix: fix some key offsets for IP4_TCP_UDP VCAP IS2 entries inet_diag: validate INET_DIAG_REQ_PROTOCOL attribute net: bridge: br_vlan_get_pvid_rcu() should dereference the VLAN group under RCU net: Update MAINTAINERS for MediaTek switch driver net/mlx5e: mlx5e_fec_in_caps() returns a boolean net/mlx5e: kTLS, Avoid kzalloc(GFP_KERNEL) under spinlock net/mlx5e: kTLS, Fix leak on resync error flow net/mlx5e: kTLS, Add missing dma_unmap in RX resync net/mlx5e: kTLS, Fix napi sync and possible use-after-free net/mlx5e: TLS, Do not expose FPGA TLS counter if not supported net/mlx5e: Fix using wrong stats_grps in mlx5e_update_ndo_stats() net/mlx5e: Fix multicast counter not up-to-date in "ip -s" net/mlx5e: Fix endianness when calculating pedit mask first bit net/mlx5e: Enable adding peer miss rules only if merged eswitch is supported net/mlx5e: CT: Fix freeing ct_label mapping net/mlx5e: Fix memory leak of tunnel info when rule under multipath not ready net/mlx5e: Use synchronize_rcu to sync with NAPI net/mlx5e: Use RCU to protect rq->xdp_prog ...
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/seq_file.h>
|
||||
@@ -83,11 +84,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
|
||||
*/
|
||||
static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
|
||||
{
|
||||
const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
|
||||
const struct batadv_bla_backbone_gw *gw;
|
||||
u32 hash = 0;
|
||||
|
||||
hash = jhash(&claim->addr, sizeof(claim->addr), hash);
|
||||
hash = jhash(&claim->vid, sizeof(claim->vid), hash);
|
||||
gw = (struct batadv_bla_backbone_gw *)data;
|
||||
hash = jhash(&gw->orig, sizeof(gw->orig), hash);
|
||||
hash = jhash(&gw->vid, sizeof(gw->vid), hash);
|
||||
|
||||
return hash % size;
|
||||
}
|
||||
@@ -1579,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||
* batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: contains the bcast_packet to be checked
|
||||
* @skb: contains the multicast packet to be checked
|
||||
* @payload_ptr: pointer to position inside the head buffer of the skb
|
||||
* marking the start of the data to be CRC'ed
|
||||
* @orig: originator mac address, NULL if unknown
|
||||
*
|
||||
* check if it is on our broadcast list. Another gateway might
|
||||
* have sent the same packet because it is connected to the same backbone,
|
||||
* so we have to remove this duplicate.
|
||||
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||
* same packet because it is connected to the same backbone, so we have to
|
||||
* remove this duplicate.
|
||||
*
|
||||
* This is performed by checking the CRC, which will tell us
|
||||
* with a good chance that it is the same packet. If it is furthermore
|
||||
@@ -1594,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
|
||||
*
|
||||
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||
*/
|
||||
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb)
|
||||
static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb, u8 *payload_ptr,
|
||||
const u8 *orig)
|
||||
{
|
||||
int i, curr;
|
||||
__be32 crc;
|
||||
struct batadv_bcast_packet *bcast_packet;
|
||||
struct batadv_bcast_duplist_entry *entry;
|
||||
bool ret = false;
|
||||
|
||||
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||
int i, curr;
|
||||
__be32 crc;
|
||||
|
||||
/* calculate the crc ... */
|
||||
crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
|
||||
crc = batadv_skb_crc32(skb, payload_ptr);
|
||||
|
||||
spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
|
||||
|
||||
@@ -1625,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||
if (entry->crc != crc)
|
||||
continue;
|
||||
|
||||
if (batadv_compare_eth(entry->orig, bcast_packet->orig))
|
||||
continue;
|
||||
/* are the originators both known and not anonymous? */
|
||||
if (orig && !is_zero_ether_addr(orig) &&
|
||||
!is_zero_ether_addr(entry->orig)) {
|
||||
/* If known, check if the new frame came from
|
||||
* the same originator:
|
||||
* We are safe to take identical frames from the
|
||||
* same orig, if known, as multiplications in
|
||||
* the mesh are detected via the (orig, seqno) pair.
|
||||
* So we can be a bit more liberal here and allow
|
||||
* identical frames from the same orig which the source
|
||||
* host might have sent multiple times on purpose.
|
||||
*/
|
||||
if (batadv_compare_eth(entry->orig, orig))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* this entry seems to match: same crc, not too old,
|
||||
* and from another gw. therefore return true to forbid it.
|
||||
@@ -1642,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||
entry = &bat_priv->bla.bcast_duplist[curr];
|
||||
entry->crc = crc;
|
||||
entry->entrytime = jiffies;
|
||||
ether_addr_copy(entry->orig, bcast_packet->orig);
|
||||
|
||||
/* known originator */
|
||||
if (orig)
|
||||
ether_addr_copy(entry->orig, orig);
|
||||
/* anonymous originator */
|
||||
else
|
||||
eth_zero_addr(entry->orig);
|
||||
|
||||
bat_priv->bla.bcast_duplist_curr = curr;
|
||||
|
||||
out:
|
||||
@@ -1651,6 +1674,48 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: contains the multicast packet to be checked, decapsulated from a
|
||||
* unicast_packet
|
||||
*
|
||||
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||
* same packet because it is connected to the same backbone, so we have to
|
||||
* remove this duplicate.
|
||||
*
|
||||
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||
*/
|
||||
static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: contains the bcast_packet to be checked
|
||||
*
|
||||
* Check if it is on our broadcast list. Another gateway might have sent the
|
||||
* same packet because it is connected to the same backbone, so we have to
|
||||
* remove this duplicate.
|
||||
*
|
||||
* Return: true if a packet is in the duplicate list, false otherwise.
|
||||
*/
|
||||
bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct batadv_bcast_packet *bcast_packet;
|
||||
u8 *payload_ptr;
|
||||
|
||||
bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||
payload_ptr = (u8 *)(bcast_packet + 1);
|
||||
|
||||
return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
|
||||
bcast_packet->orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
|
||||
* the VLAN identified by vid.
|
||||
@@ -1812,7 +1877,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: the frame to be checked
|
||||
* @vid: the VLAN ID of the frame
|
||||
* @is_bcast: the packet came in a broadcast packet type.
|
||||
* @packet_type: the batman packet type this frame came in
|
||||
*
|
||||
* batadv_bla_rx avoidance checks if:
|
||||
* * we have to race for a claim
|
||||
@@ -1824,7 +1889,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
* further process the skb.
|
||||
*/
|
||||
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
unsigned short vid, bool is_bcast)
|
||||
unsigned short vid, int packet_type)
|
||||
{
|
||||
struct batadv_bla_backbone_gw *backbone_gw;
|
||||
struct ethhdr *ethhdr;
|
||||
@@ -1846,9 +1911,32 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
goto handled;
|
||||
|
||||
if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
|
||||
/* don't allow broadcasts while requests are in flight */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
|
||||
goto handled;
|
||||
/* don't allow multicast packets while requests are in flight */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||
/* Both broadcast flooding or multicast-via-unicasts
|
||||
* delivery might send to multiple backbone gateways
|
||||
* sharing the same LAN and therefore need to coordinate
|
||||
* which backbone gateway forwards into the LAN,
|
||||
* by claiming the payload source address.
|
||||
*
|
||||
* Broadcast flooding and multicast-via-unicasts
|
||||
* delivery use the following two batman packet types.
|
||||
* Note: explicitly exclude BATADV_UNICAST_4ADDR,
|
||||
* as the DHCP gateway feature will send explicitly
|
||||
* to only one BLA gateway, so the claiming process
|
||||
* should be avoided there.
|
||||
*/
|
||||
if (packet_type == BATADV_BCAST ||
|
||||
packet_type == BATADV_UNICAST)
|
||||
goto handled;
|
||||
|
||||
/* potential duplicates from foreign BLA backbone gateways via
|
||||
* multicast-in-unicast packets
|
||||
*/
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||
packet_type == BATADV_UNICAST &&
|
||||
batadv_bla_check_ucast_duplist(bat_priv, skb))
|
||||
goto handled;
|
||||
|
||||
ether_addr_copy(search_claim.addr, ethhdr->h_source);
|
||||
search_claim.vid = vid;
|
||||
@@ -1883,13 +1971,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
goto allow;
|
||||
}
|
||||
|
||||
/* if it is a broadcast ... */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
|
||||
/* if it is a multicast ... */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest) &&
|
||||
(packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
|
||||
/* ... drop it. the responsible gateway is in charge.
|
||||
*
|
||||
* We need to check is_bcast because with the gateway
|
||||
* We need to check packet type because with the gateway
|
||||
* feature, broadcasts (like DHCP requests) may be sent
|
||||
* using a unicast packet type.
|
||||
* using a unicast 4 address packet type. See comment above.
|
||||
*/
|
||||
goto handled;
|
||||
} else {
|
||||
|
||||
@@ -35,7 +35,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
|
||||
|
||||
#ifdef CONFIG_BATMAN_ADV_BLA
|
||||
bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
unsigned short vid, bool is_bcast);
|
||||
unsigned short vid, int packet_type);
|
||||
bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
unsigned short vid);
|
||||
bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
|
||||
@@ -66,7 +66,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
|
||||
|
||||
static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb, unsigned short vid,
|
||||
bool is_bcast)
|
||||
int packet_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
+36
-10
@@ -51,6 +51,7 @@
|
||||
#include <uapi/linux/batadv_packet.h>
|
||||
#include <uapi/linux/batman_adv.h>
|
||||
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "hard-interface.h"
|
||||
#include "hash.h"
|
||||
#include "log.h"
|
||||
@@ -1434,6 +1435,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
return BATADV_FORW_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_mcast_forw_send_orig() - send a multicast packet to an originator
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: the multicast packet to send
|
||||
* @vid: the vlan identifier
|
||||
* @orig_node: the originator to send the packet to
|
||||
*
|
||||
* Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
|
||||
*/
|
||||
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb,
|
||||
unsigned short vid,
|
||||
struct batadv_orig_node *orig_node)
|
||||
{
|
||||
/* Avoid sending multicast-in-unicast packets to other BLA
|
||||
* gateways - they already got the frame from the LAN side
|
||||
* we share with them.
|
||||
* TODO: Refactor to take BLA into account earlier, to avoid
|
||||
* reducing the mcast_fanout count.
|
||||
*/
|
||||
if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
|
||||
dev_kfree_skb(skb);
|
||||
return NET_XMIT_SUCCESS;
|
||||
}
|
||||
|
||||
return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
|
||||
orig_node, vid);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_mcast_forw_tt() - forwards a packet to multicast listeners
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
@@ -1471,8 +1501,8 @@ batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
break;
|
||||
}
|
||||
|
||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||
orig_entry->orig_node, vid);
|
||||
batadv_mcast_forw_send_orig(bat_priv, newskb, vid,
|
||||
orig_entry->orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -1513,8 +1543,7 @@ batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv,
|
||||
break;
|
||||
}
|
||||
|
||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||
orig_node, vid);
|
||||
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
@@ -1551,8 +1580,7 @@ batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv,
|
||||
break;
|
||||
}
|
||||
|
||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||
orig_node, vid);
|
||||
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
@@ -1618,8 +1646,7 @@ batadv_mcast_forw_want_all_rtr4(struct batadv_priv *bat_priv,
|
||||
break;
|
||||
}
|
||||
|
||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||
orig_node, vid);
|
||||
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
@@ -1656,8 +1683,7 @@ batadv_mcast_forw_want_all_rtr6(struct batadv_priv *bat_priv,
|
||||
break;
|
||||
}
|
||||
|
||||
batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0,
|
||||
orig_node, vid);
|
||||
batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
|
||||
@@ -46,6 +46,11 @@ enum batadv_forw_mode
|
||||
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
struct batadv_orig_node **mcast_single_orig);
|
||||
|
||||
int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb,
|
||||
unsigned short vid,
|
||||
struct batadv_orig_node *orig_node);
|
||||
|
||||
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
unsigned short vid);
|
||||
|
||||
@@ -71,6 +76,16 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
return BATADV_FORW_ALL;
|
||||
}
|
||||
|
||||
static inline int
|
||||
batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb,
|
||||
unsigned short vid,
|
||||
struct batadv_orig_node *orig_node)
|
||||
{
|
||||
kfree_skb(skb);
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
static inline int
|
||||
batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||
unsigned short vid)
|
||||
|
||||
@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||
vid = batadv_get_vid(skb, hdr_len);
|
||||
ethhdr = (struct ethhdr *)(skb->data + hdr_len);
|
||||
|
||||
/* do not reroute multicast frames in a unicast header */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest))
|
||||
return true;
|
||||
|
||||
/* check if the destination client was served by this node and it is now
|
||||
* roaming. In this case, it means that the node has got a ROAM_ADV
|
||||
* message and that it knows the new destination in the mesh to re-route
|
||||
|
||||
@@ -364,9 +364,8 @@ send:
|
||||
goto dropped;
|
||||
ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
|
||||
} else if (mcast_single_orig) {
|
||||
ret = batadv_send_skb_unicast(bat_priv, skb,
|
||||
BATADV_UNICAST, 0,
|
||||
mcast_single_orig, vid);
|
||||
ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
|
||||
mcast_single_orig);
|
||||
} else if (forw_mode == BATADV_FORW_SOME) {
|
||||
ret = batadv_mcast_forw_send(bat_priv, skb, vid);
|
||||
} else {
|
||||
@@ -425,10 +424,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
||||
struct vlan_ethhdr *vhdr;
|
||||
struct ethhdr *ethhdr;
|
||||
unsigned short vid;
|
||||
bool is_bcast;
|
||||
int packet_type;
|
||||
|
||||
batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
|
||||
is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
|
||||
packet_type = batadv_bcast_packet->packet_type;
|
||||
|
||||
skb_pull_rcsum(skb, hdr_size);
|
||||
skb_reset_mac_header(skb);
|
||||
@@ -471,7 +470,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
|
||||
/* Let the bridge loop avoidance check the packet. If will
|
||||
* not handle it, we can safely push it up.
|
||||
*/
|
||||
if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
|
||||
if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
|
||||
goto out;
|
||||
|
||||
if (orig_node)
|
||||
|
||||
+17
-10
@@ -1288,11 +1288,13 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
|
||||
}
|
||||
}
|
||||
|
||||
static int __br_vlan_get_pvid(const struct net_device *dev,
|
||||
struct net_bridge_port *p, u16 *p_pvid)
|
||||
int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
|
||||
{
|
||||
struct net_bridge_vlan_group *vg;
|
||||
struct net_bridge_port *p;
|
||||
|
||||
ASSERT_RTNL();
|
||||
p = br_port_get_check_rtnl(dev);
|
||||
if (p)
|
||||
vg = nbp_vlan_group(p);
|
||||
else if (netif_is_bridge_master(dev))
|
||||
@@ -1303,18 +1305,23 @@ static int __br_vlan_get_pvid(const struct net_device *dev,
|
||||
*p_pvid = br_get_pvid(vg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid)
|
||||
{
|
||||
ASSERT_RTNL();
|
||||
|
||||
return __br_vlan_get_pvid(dev, br_port_get_check_rtnl(dev), p_pvid);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(br_vlan_get_pvid);
|
||||
|
||||
int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid)
|
||||
{
|
||||
return __br_vlan_get_pvid(dev, br_port_get_check_rcu(dev), p_pvid);
|
||||
struct net_bridge_vlan_group *vg;
|
||||
struct net_bridge_port *p;
|
||||
|
||||
p = br_port_get_check_rcu(dev);
|
||||
if (p)
|
||||
vg = nbp_vlan_group_rcu(p);
|
||||
else if (netif_is_bridge_master(dev))
|
||||
vg = br_vlan_group_rcu(netdev_priv(dev));
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
*p_pvid = br_get_pvid(vg);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);
|
||||
|
||||
|
||||
+1
-1
@@ -8647,7 +8647,7 @@ int dev_get_port_parent_id(struct net_device *dev,
|
||||
if (!first.id_len)
|
||||
first = *ppid;
|
||||
else if (memcmp(&first, ppid, sizeof(*ppid)))
|
||||
return -ENODATA;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ static void dst_destroy_rcu(struct rcu_head *head)
|
||||
|
||||
/* Operations to mark dst as DEAD and clean up the net device referenced
|
||||
* by dst:
|
||||
* 1. put the dst under loopback interface and discard all tx/rx packets
|
||||
* 1. put the dst under blackhole interface and discard all tx/rx packets
|
||||
* on this route.
|
||||
* 2. release the net_device
|
||||
* This function should be called when removing routes from the fib tree
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <net/ip_tunnels.h>
|
||||
#include <linux/indirect_call_wrapper.h>
|
||||
|
||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||
#if defined(CONFIG_IPV6) && defined(CONFIG_IPV6_MULTIPLE_TABLES)
|
||||
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
||||
#define INDIRECT_CALL_MT(f, f2, f1, ...) \
|
||||
INDIRECT_CALL_INET(f, f2, f1, __VA_ARGS__)
|
||||
|
||||
+10
-9
@@ -4838,6 +4838,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
|
||||
fl4.saddr = params->ipv4_src;
|
||||
fl4.fl4_sport = params->sport;
|
||||
fl4.fl4_dport = params->dport;
|
||||
fl4.flowi4_multipath_hash = 0;
|
||||
|
||||
if (flags & BPF_FIB_LOOKUP_DIRECT) {
|
||||
u32 tbid = l3mdev_fib_table_rcu(dev) ? : RT_TABLE_MAIN;
|
||||
@@ -7065,8 +7066,6 @@ static int bpf_gen_ld_abs(const struct bpf_insn *orig,
|
||||
bool indirect = BPF_MODE(orig->code) == BPF_IND;
|
||||
struct bpf_insn *insn = insn_buf;
|
||||
|
||||
/* We're guaranteed here that CTX is in R6. */
|
||||
*insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_CTX);
|
||||
if (!indirect) {
|
||||
*insn++ = BPF_MOV64_IMM(BPF_REG_2, orig->imm);
|
||||
} else {
|
||||
@@ -7074,6 +7073,8 @@ static int bpf_gen_ld_abs(const struct bpf_insn *orig,
|
||||
if (orig->imm)
|
||||
*insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, orig->imm);
|
||||
}
|
||||
/* We're guaranteed here that CTX is in R6. */
|
||||
*insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_CTX);
|
||||
|
||||
switch (BPF_SIZE(orig->code)) {
|
||||
case BPF_B:
|
||||
@@ -9522,7 +9523,7 @@ BPF_CALL_1(bpf_skc_to_tcp6_sock, struct sock *, sk)
|
||||
* trigger an explicit type generation here.
|
||||
*/
|
||||
BTF_TYPE_EMIT(struct tcp6_sock);
|
||||
if (sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP &&
|
||||
if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP &&
|
||||
sk->sk_family == AF_INET6)
|
||||
return (unsigned long)sk;
|
||||
|
||||
@@ -9540,7 +9541,7 @@ const struct bpf_func_proto bpf_skc_to_tcp6_sock_proto = {
|
||||
|
||||
BPF_CALL_1(bpf_skc_to_tcp_sock, struct sock *, sk)
|
||||
{
|
||||
if (sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP)
|
||||
if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP)
|
||||
return (unsigned long)sk;
|
||||
|
||||
return (unsigned long)NULL;
|
||||
@@ -9558,12 +9559,12 @@ const struct bpf_func_proto bpf_skc_to_tcp_sock_proto = {
|
||||
BPF_CALL_1(bpf_skc_to_tcp_timewait_sock, struct sock *, sk)
|
||||
{
|
||||
#ifdef CONFIG_INET
|
||||
if (sk->sk_prot == &tcp_prot && sk->sk_state == TCP_TIME_WAIT)
|
||||
if (sk && sk->sk_prot == &tcp_prot && sk->sk_state == TCP_TIME_WAIT)
|
||||
return (unsigned long)sk;
|
||||
#endif
|
||||
|
||||
#if IS_BUILTIN(CONFIG_IPV6)
|
||||
if (sk->sk_prot == &tcpv6_prot && sk->sk_state == TCP_TIME_WAIT)
|
||||
if (sk && sk->sk_prot == &tcpv6_prot && sk->sk_state == TCP_TIME_WAIT)
|
||||
return (unsigned long)sk;
|
||||
#endif
|
||||
|
||||
@@ -9582,12 +9583,12 @@ const struct bpf_func_proto bpf_skc_to_tcp_timewait_sock_proto = {
|
||||
BPF_CALL_1(bpf_skc_to_tcp_request_sock, struct sock *, sk)
|
||||
{
|
||||
#ifdef CONFIG_INET
|
||||
if (sk->sk_prot == &tcp_prot && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
if (sk && sk->sk_prot == &tcp_prot && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
return (unsigned long)sk;
|
||||
#endif
|
||||
|
||||
#if IS_BUILTIN(CONFIG_IPV6)
|
||||
if (sk->sk_prot == &tcpv6_prot && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
if (sk && sk->sk_prot == &tcpv6_prot && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
return (unsigned long)sk;
|
||||
#endif
|
||||
|
||||
@@ -9609,7 +9610,7 @@ BPF_CALL_1(bpf_skc_to_udp6_sock, struct sock *, sk)
|
||||
* trigger an explicit type generation here.
|
||||
*/
|
||||
BTF_TYPE_EMIT(struct udp6_sock);
|
||||
if (sk_fullsock(sk) && sk->sk_protocol == IPPROTO_UDP &&
|
||||
if (sk && sk_fullsock(sk) && sk->sk_protocol == IPPROTO_UDP &&
|
||||
sk->sk_type == SOCK_DGRAM && sk->sk_family == AF_INET6)
|
||||
return (unsigned long)sk;
|
||||
|
||||
|
||||
+11
-11
@@ -251,10 +251,10 @@ int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
|
||||
if (refcount_read(&net->count) == 0)
|
||||
return NETNSA_NSID_NOT_ASSIGNED;
|
||||
|
||||
spin_lock(&net->nsid_lock);
|
||||
spin_lock_bh(&net->nsid_lock);
|
||||
id = __peernet2id(net, peer);
|
||||
if (id >= 0) {
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -264,12 +264,12 @@ int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp)
|
||||
* just been idr_remove()'d from there in cleanup_net().
|
||||
*/
|
||||
if (!maybe_get_net(peer)) {
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
return NETNSA_NSID_NOT_ASSIGNED;
|
||||
}
|
||||
|
||||
id = alloc_netid(net, peer, -1);
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
|
||||
put_net(peer);
|
||||
if (id < 0)
|
||||
@@ -534,20 +534,20 @@ static void unhash_nsid(struct net *net, struct net *last)
|
||||
for_each_net(tmp) {
|
||||
int id;
|
||||
|
||||
spin_lock(&tmp->nsid_lock);
|
||||
spin_lock_bh(&tmp->nsid_lock);
|
||||
id = __peernet2id(tmp, net);
|
||||
if (id >= 0)
|
||||
idr_remove(&tmp->netns_ids, id);
|
||||
spin_unlock(&tmp->nsid_lock);
|
||||
spin_unlock_bh(&tmp->nsid_lock);
|
||||
if (id >= 0)
|
||||
rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL,
|
||||
GFP_KERNEL);
|
||||
if (tmp == last)
|
||||
break;
|
||||
}
|
||||
spin_lock(&net->nsid_lock);
|
||||
spin_lock_bh(&net->nsid_lock);
|
||||
idr_destroy(&net->netns_ids);
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
}
|
||||
|
||||
static LLIST_HEAD(cleanup_list);
|
||||
@@ -760,9 +760,9 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
return PTR_ERR(peer);
|
||||
}
|
||||
|
||||
spin_lock(&net->nsid_lock);
|
||||
spin_lock_bh(&net->nsid_lock);
|
||||
if (__peernet2id(net, peer) >= 0) {
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
err = -EEXIST;
|
||||
NL_SET_BAD_ATTR(extack, nla);
|
||||
NL_SET_ERR_MSG(extack,
|
||||
@@ -771,7 +771,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
}
|
||||
|
||||
err = alloc_netid(net, peer, nsid);
|
||||
spin_unlock(&net->nsid_lock);
|
||||
spin_unlock_bh(&net->nsid_lock);
|
||||
if (err >= 0) {
|
||||
rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid,
|
||||
nlh, GFP_KERNEL);
|
||||
|
||||
@@ -1426,6 +1426,7 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
|
||||
{
|
||||
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
|
||||
struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
|
||||
int prio;
|
||||
int err;
|
||||
|
||||
if (!ops)
|
||||
@@ -1475,6 +1476,13 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
|
||||
struct dcbnl_buffer *buffer =
|
||||
nla_data(ieee[DCB_ATTR_DCB_BUFFER]);
|
||||
|
||||
for (prio = 0; prio < ARRAY_SIZE(buffer->prio2buffer); prio++) {
|
||||
if (buffer->prio2buffer[prio] >= DCBX_MAX_BUFFERS) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
err = ops->dcbnl_setbuffer(netdev, buffer);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
+16
-2
@@ -1799,15 +1799,27 @@ int dsa_slave_create(struct dsa_port *port)
|
||||
|
||||
dsa_slave_notify(slave_dev, DSA_PORT_REGISTER);
|
||||
|
||||
ret = register_netdev(slave_dev);
|
||||
rtnl_lock();
|
||||
|
||||
ret = register_netdevice(slave_dev);
|
||||
if (ret) {
|
||||
netdev_err(master, "error %d registering interface %s\n",
|
||||
ret, slave_dev->name);
|
||||
rtnl_unlock();
|
||||
goto out_phy;
|
||||
}
|
||||
|
||||
ret = netdev_upper_dev_link(master, slave_dev, NULL);
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
if (ret)
|
||||
goto out_unregister;
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
unregister_netdev(slave_dev);
|
||||
out_phy:
|
||||
rtnl_lock();
|
||||
phylink_disconnect_phy(p->dp->pl);
|
||||
@@ -1824,16 +1836,18 @@ out_free:
|
||||
|
||||
void dsa_slave_destroy(struct net_device *slave_dev)
|
||||
{
|
||||
struct net_device *master = dsa_slave_to_master(slave_dev);
|
||||
struct dsa_port *dp = dsa_slave_to_port(slave_dev);
|
||||
struct dsa_slave_priv *p = netdev_priv(slave_dev);
|
||||
|
||||
netif_carrier_off(slave_dev);
|
||||
rtnl_lock();
|
||||
netdev_upper_dev_unlink(master, slave_dev);
|
||||
unregister_netdevice(slave_dev);
|
||||
phylink_disconnect_phy(dp->pl);
|
||||
rtnl_unlock();
|
||||
|
||||
dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER);
|
||||
unregister_netdev(slave_dev);
|
||||
phylink_destroy(dp->pl);
|
||||
gro_cells_destroy(&p->gcells);
|
||||
free_percpu(p->stats64);
|
||||
|
||||
@@ -160,11 +160,14 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
|
||||
packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0);
|
||||
|
||||
if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
|
||||
struct sk_buff *clone = DSA_SKB_CB(skb)->clone;
|
||||
|
||||
rew_op = ocelot_port->ptp_cmd;
|
||||
if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
|
||||
rew_op |= (ocelot_port->ts_id % 4) << 3;
|
||||
ocelot_port->ts_id++;
|
||||
}
|
||||
/* Retrieve timestamp ID populated inside skb->cb[0] of the
|
||||
* clone by ocelot_port_add_txtstamp_skb
|
||||
*/
|
||||
if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
|
||||
rew_op |= clone->cb[0] << 3;
|
||||
|
||||
packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ int ethnl_tunnel_info_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
reply_len = ret + ethnl_reply_header_size();
|
||||
|
||||
rskb = ethnl_reply_init(reply_len, req_info.dev,
|
||||
ETHTOOL_MSG_TUNNEL_INFO_GET,
|
||||
ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY,
|
||||
ETHTOOL_A_TUNNEL_INFO_HEADER,
|
||||
info, &reply_payload);
|
||||
if (!rskb) {
|
||||
@@ -273,7 +273,7 @@ int ethnl_tunnel_info_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
goto cont;
|
||||
|
||||
ehdr = ethnl_dump_put(skb, cb,
|
||||
ETHTOOL_MSG_TUNNEL_INFO_GET);
|
||||
ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY);
|
||||
if (!ehdr) {
|
||||
ret = -EMSGSIZE;
|
||||
goto out;
|
||||
|
||||
@@ -76,7 +76,7 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
|
||||
proto = nla_get_u8(data[IFLA_HSR_PROTOCOL]);
|
||||
|
||||
if (proto >= HSR_PROTOCOL_MAX) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol\n");
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -84,14 +84,14 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
|
||||
proto_version = HSR_V0;
|
||||
} else {
|
||||
if (proto == HSR_PROTOCOL_PRP) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported\n");
|
||||
NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
proto_version = nla_get_u8(data[IFLA_HSR_VERSION]);
|
||||
if (proto_version > HSR_V1) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Only HSR version 0/1 supported\n");
|
||||
"Only HSR version 0/1 supported");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,6 +362,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
|
||||
fl4.flowi4_tun_key.tun_id = 0;
|
||||
fl4.flowi4_flags = 0;
|
||||
fl4.flowi4_uid = sock_net_uid(net, NULL);
|
||||
fl4.flowi4_multipath_hash = 0;
|
||||
|
||||
no_addr = idev->ifa_list == NULL;
|
||||
|
||||
|
||||
+15
-5
@@ -186,8 +186,8 @@ errout:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(inet_diag_msg_attrs_fill);
|
||||
|
||||
static void inet_diag_parse_attrs(const struct nlmsghdr *nlh, int hdrlen,
|
||||
struct nlattr **req_nlas)
|
||||
static int inet_diag_parse_attrs(const struct nlmsghdr *nlh, int hdrlen,
|
||||
struct nlattr **req_nlas)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int remaining;
|
||||
@@ -195,9 +195,13 @@ static void inet_diag_parse_attrs(const struct nlmsghdr *nlh, int hdrlen,
|
||||
nlmsg_for_each_attr(nla, nlh, hdrlen, remaining) {
|
||||
int type = nla_type(nla);
|
||||
|
||||
if (type == INET_DIAG_REQ_PROTOCOL && nla_len(nla) != sizeof(u32))
|
||||
return -EINVAL;
|
||||
|
||||
if (type < __INET_DIAG_REQ_MAX)
|
||||
req_nlas[type] = nla;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inet_diag_get_protocol(const struct inet_diag_req_v2 *req,
|
||||
@@ -574,7 +578,10 @@ static int inet_diag_cmd_exact(int cmd, struct sk_buff *in_skb,
|
||||
int err, protocol;
|
||||
|
||||
memset(&dump_data, 0, sizeof(dump_data));
|
||||
inet_diag_parse_attrs(nlh, hdrlen, dump_data.req_nlas);
|
||||
err = inet_diag_parse_attrs(nlh, hdrlen, dump_data.req_nlas);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
protocol = inet_diag_get_protocol(req, &dump_data);
|
||||
|
||||
handler = inet_diag_lock_handler(protocol);
|
||||
@@ -1180,8 +1187,11 @@ static int __inet_diag_dump_start(struct netlink_callback *cb, int hdrlen)
|
||||
if (!cb_data)
|
||||
return -ENOMEM;
|
||||
|
||||
inet_diag_parse_attrs(nlh, hdrlen, cb_data->req_nlas);
|
||||
|
||||
err = inet_diag_parse_attrs(nlh, hdrlen, cb_data->req_nlas);
|
||||
if (err) {
|
||||
kfree(cb_data);
|
||||
return err;
|
||||
}
|
||||
nla = cb_data->inet_diag_nla_bc;
|
||||
if (nla) {
|
||||
err = inet_diag_bc_audit(nla, skb);
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#include <net/icmp.h>
|
||||
#include <net/checksum.h>
|
||||
#include <net/inetpeer.h>
|
||||
#include <net/inet_ecn.h>
|
||||
#include <net/lwtunnel.h>
|
||||
#include <linux/bpf-cgroup.h>
|
||||
#include <linux/igmp.h>
|
||||
@@ -1703,7 +1704,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
|
||||
if (IS_ERR(rt))
|
||||
return;
|
||||
|
||||
inet_sk(sk)->tos = arg->tos;
|
||||
inet_sk(sk)->tos = arg->tos & ~INET_ECN_MASK;
|
||||
|
||||
sk->sk_protocol = ip_hdr(skb)->protocol;
|
||||
sk->sk_bound_dev_if = arg->bound_dev_if;
|
||||
|
||||
@@ -554,6 +554,7 @@ static int ip_tun_parse_opts_vxlan(struct nlattr *attr,
|
||||
|
||||
attr = tb[LWTUNNEL_IP_OPT_VXLAN_GBP];
|
||||
md->gbp = nla_get_u32(attr);
|
||||
md->gbp &= VXLAN_GBP_MASK;
|
||||
info->key.tun_flags |= TUNNEL_VXLAN_OPT;
|
||||
}
|
||||
|
||||
|
||||
+9
-5
@@ -786,8 +786,10 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
|
||||
neigh_event_send(n, NULL);
|
||||
} else {
|
||||
if (fib_lookup(net, fl4, &res, 0) == 0) {
|
||||
struct fib_nh_common *nhc = FIB_RES_NHC(res);
|
||||
struct fib_nh_common *nhc;
|
||||
|
||||
fib_select_path(net, &res, fl4, skb);
|
||||
nhc = FIB_RES_NHC(res);
|
||||
update_or_create_fnhe(nhc, fl4->daddr, new_gw,
|
||||
0, false,
|
||||
jiffies + ip_rt_gc_timeout);
|
||||
@@ -1013,6 +1015,7 @@ out: kfree_skb(skb);
|
||||
static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
{
|
||||
struct dst_entry *dst = &rt->dst;
|
||||
struct net *net = dev_net(dst->dev);
|
||||
u32 old_mtu = ipv4_mtu(dst);
|
||||
struct fib_result res;
|
||||
bool lock = false;
|
||||
@@ -1033,9 +1036,11 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) {
|
||||
struct fib_nh_common *nhc = FIB_RES_NHC(res);
|
||||
if (fib_lookup(net, fl4, &res, 0) == 0) {
|
||||
struct fib_nh_common *nhc;
|
||||
|
||||
fib_select_path(net, &res, fl4, NULL);
|
||||
nhc = FIB_RES_NHC(res);
|
||||
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
|
||||
jiffies + ip_rt_mtu_expires);
|
||||
}
|
||||
@@ -2147,6 +2152,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
||||
fl4.daddr = daddr;
|
||||
fl4.saddr = saddr;
|
||||
fl4.flowi4_uid = sock_net_uid(net, NULL);
|
||||
fl4.flowi4_multipath_hash = 0;
|
||||
|
||||
if (fib4_rules_early_flow_dissect(net, skb, &fl4, &_flkeys)) {
|
||||
flkeys = &_flkeys;
|
||||
@@ -2667,8 +2673,6 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4,
|
||||
fib_select_path(net, res, fl4, skb);
|
||||
|
||||
dev_out = FIB_RES_DEV(*res);
|
||||
fl4->flowi4_oif = dev_out->ifindex;
|
||||
|
||||
|
||||
make_route:
|
||||
rth = __mkroute_output(res, fl4, orig_oif, dev_out, flags);
|
||||
|
||||
@@ -303,6 +303,7 @@ config IPV6_SEG6_LWTUNNEL
|
||||
config IPV6_SEG6_HMAC
|
||||
bool "IPv6: Segment Routing HMAC support"
|
||||
depends on IPV6
|
||||
select CRYPTO
|
||||
select CRYPTO_HMAC
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_SHA256
|
||||
|
||||
+9
-4
@@ -1993,14 +1993,19 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
|
||||
/* Need to own table->tb6_lock */
|
||||
int fib6_del(struct fib6_info *rt, struct nl_info *info)
|
||||
{
|
||||
struct fib6_node *fn = rcu_dereference_protected(rt->fib6_node,
|
||||
lockdep_is_held(&rt->fib6_table->tb6_lock));
|
||||
struct fib6_table *table = rt->fib6_table;
|
||||
struct net *net = info->nl_net;
|
||||
struct fib6_info __rcu **rtp;
|
||||
struct fib6_info __rcu **rtp_next;
|
||||
struct fib6_table *table;
|
||||
struct fib6_node *fn;
|
||||
|
||||
if (!fn || rt == net->ipv6.fib6_null_entry)
|
||||
if (rt == net->ipv6.fib6_null_entry)
|
||||
return -ENOENT;
|
||||
|
||||
table = rt->fib6_table;
|
||||
fn = rcu_dereference_protected(rt->fib6_node,
|
||||
lockdep_is_held(&table->tb6_lock));
|
||||
if (!fn)
|
||||
return -ENOENT;
|
||||
|
||||
WARN_ON(!(fn->fn_flags & RTN_RTINFO));
|
||||
|
||||
+1
-1
@@ -4202,7 +4202,7 @@ static struct fib6_info *rt6_add_route_info(struct net *net,
|
||||
.fc_nlinfo.nl_net = net,
|
||||
};
|
||||
|
||||
cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO,
|
||||
cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO;
|
||||
cfg.fc_dst = *prefix;
|
||||
cfg.fc_gateway = *gwaddr;
|
||||
|
||||
|
||||
+14
-6
@@ -560,7 +560,9 @@ static int ieee80211_fill_rx_status(struct ieee80211_rx_status *stat,
|
||||
if (rate->idx < 0 || !rate->count)
|
||||
return -1;
|
||||
|
||||
if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
|
||||
stat->bw = RATE_INFO_BW_160;
|
||||
else if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
|
||||
stat->bw = RATE_INFO_BW_80;
|
||||
else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
stat->bw = RATE_INFO_BW_40;
|
||||
@@ -668,20 +670,26 @@ u32 ieee80211_calc_expected_tx_airtime(struct ieee80211_hw *hw,
|
||||
* This will not be very accurate, but much better than simply
|
||||
* assuming un-aggregated tx in all cases.
|
||||
*/
|
||||
if (duration > 400) /* <= VHT20 MCS2 1S */
|
||||
if (duration > 400 * 1024) /* <= VHT20 MCS2 1S */
|
||||
agg_shift = 1;
|
||||
else if (duration > 250) /* <= VHT20 MCS3 1S or MCS1 2S */
|
||||
else if (duration > 250 * 1024) /* <= VHT20 MCS3 1S or MCS1 2S */
|
||||
agg_shift = 2;
|
||||
else if (duration > 150) /* <= VHT20 MCS5 1S or MCS3 2S */
|
||||
else if (duration > 150 * 1024) /* <= VHT20 MCS5 1S or MCS2 2S */
|
||||
agg_shift = 3;
|
||||
else
|
||||
else if (duration > 70 * 1024) /* <= VHT20 MCS5 2S */
|
||||
agg_shift = 4;
|
||||
else if (stat.encoding != RX_ENC_HE ||
|
||||
duration > 20 * 1024) /* <= HE40 MCS6 2S */
|
||||
agg_shift = 5;
|
||||
else
|
||||
agg_shift = 6;
|
||||
|
||||
duration *= len;
|
||||
duration /= AVG_PKT_SIZE;
|
||||
duration /= 1024;
|
||||
duration += (overhead >> agg_shift);
|
||||
|
||||
return duration + (overhead >> agg_shift);
|
||||
return max_t(u32, duration, 4);
|
||||
}
|
||||
|
||||
if (!conf)
|
||||
|
||||
+2
-1
@@ -4861,6 +4861,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct cfg80211_chan_def chandef;
|
||||
bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
|
||||
bool is_5ghz = cbss->channel->band == NL80211_BAND_5GHZ;
|
||||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
int ret;
|
||||
u32 i;
|
||||
@@ -4879,7 +4880,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
if (!sband->vht_cap.vht_supported && !is_6ghz) {
|
||||
if (!sband->vht_cap.vht_supported && is_5ghz) {
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
}
|
||||
|
||||
+2
-1
@@ -451,7 +451,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
else if (status->bw == RATE_INFO_BW_5)
|
||||
channel_flags |= IEEE80211_CHAN_QUARTER;
|
||||
|
||||
if (status->band == NL80211_BAND_5GHZ)
|
||||
if (status->band == NL80211_BAND_5GHZ ||
|
||||
status->band == NL80211_BAND_6GHZ)
|
||||
channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ;
|
||||
else if (status->encoding != RX_ENC_LEGACY)
|
||||
channel_flags |= IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
|
||||
|
||||
+4
-3
@@ -3353,9 +3353,10 @@ bool ieee80211_chandef_he_6ghz_oper(struct ieee80211_sub_if_data *sdata,
|
||||
he_chandef.center_freq1 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs0,
|
||||
NL80211_BAND_6GHZ);
|
||||
he_chandef.center_freq2 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
if (support_80_80 || support_160)
|
||||
he_chandef.center_freq2 =
|
||||
ieee80211_channel_to_frequency(he_6ghz_oper->ccfs1,
|
||||
NL80211_BAND_6GHZ);
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(&he_chandef)) {
|
||||
|
||||
+4
-4
@@ -168,10 +168,7 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
|
||||
/* take some capabilities as-is */
|
||||
cap_info = le32_to_cpu(vht_cap_ie->vht_cap_info);
|
||||
vht_cap->cap = cap_info;
|
||||
vht_cap->cap &= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
|
||||
IEEE80211_VHT_CAP_RXLDPC |
|
||||
vht_cap->cap &= IEEE80211_VHT_CAP_RXLDPC |
|
||||
IEEE80211_VHT_CAP_VHT_TXOP_PS |
|
||||
IEEE80211_VHT_CAP_HTC_VHT |
|
||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
|
||||
@@ -180,6 +177,9 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
|
||||
IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
|
||||
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
|
||||
|
||||
vht_cap->cap |= min_t(u32, cap_info & IEEE80211_VHT_CAP_MAX_MPDU_MASK,
|
||||
own_cap.cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK);
|
||||
|
||||
/* and some based on our own capabilities */
|
||||
switch (own_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
|
||||
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
|
||||
|
||||
+5
-3
@@ -34,11 +34,11 @@ void ieee802154_xmit_worker(struct work_struct *work)
|
||||
if (res)
|
||||
goto err_tx;
|
||||
|
||||
ieee802154_xmit_complete(&local->hw, skb, false);
|
||||
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
ieee802154_xmit_complete(&local->hw, skb, false);
|
||||
|
||||
return;
|
||||
|
||||
err_tx:
|
||||
@@ -78,6 +78,8 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
|
||||
|
||||
/* async is priority, otherwise sync is fallback */
|
||||
if (local->ops->xmit_async) {
|
||||
unsigned int len = skb->len;
|
||||
|
||||
ret = drv_xmit_async(local, skb);
|
||||
if (ret) {
|
||||
ieee802154_wake_queue(&local->hw);
|
||||
@@ -85,7 +87,7 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
dev->stats.tx_bytes += len;
|
||||
} else {
|
||||
local->tx_skb = skb;
|
||||
queue_work(local->workqueue, &local->tx_work);
|
||||
|
||||
+16
-3
@@ -66,6 +66,16 @@ static bool addresses_equal(const struct mptcp_addr_info *a,
|
||||
return a->port == b->port;
|
||||
}
|
||||
|
||||
static bool address_zero(const struct mptcp_addr_info *addr)
|
||||
{
|
||||
struct mptcp_addr_info zero;
|
||||
|
||||
memset(&zero, 0, sizeof(zero));
|
||||
zero.family = addr->family;
|
||||
|
||||
return addresses_equal(addr, &zero, false);
|
||||
}
|
||||
|
||||
static void local_address(const struct sock_common *skc,
|
||||
struct mptcp_addr_info *addr)
|
||||
{
|
||||
@@ -171,9 +181,9 @@ static void check_work_pending(struct mptcp_sock *msk)
|
||||
|
||||
static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
|
||||
{
|
||||
struct mptcp_addr_info remote = { 0 };
|
||||
struct sock *sk = (struct sock *)msk;
|
||||
struct mptcp_pm_addr_entry *local;
|
||||
struct mptcp_addr_info remote;
|
||||
struct pm_nl_pernet *pernet;
|
||||
|
||||
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
|
||||
@@ -323,10 +333,13 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
* addr
|
||||
*/
|
||||
local_address((struct sock_common *)msk, &msk_local);
|
||||
local_address((struct sock_common *)msk, &skc_local);
|
||||
local_address((struct sock_common *)skc, &skc_local);
|
||||
if (addresses_equal(&msk_local, &skc_local, false))
|
||||
return 0;
|
||||
|
||||
if (address_zero(&skc_local))
|
||||
return 0;
|
||||
|
||||
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -341,7 +354,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct sock_common *skc)
|
||||
return ret;
|
||||
|
||||
/* address not found, add to local list */
|
||||
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
||||
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
+5
-2
@@ -1063,6 +1063,7 @@ int __mptcp_subflow_connect(struct sock *sk, int ifindex,
|
||||
struct mptcp_sock *msk = mptcp_sk(sk);
|
||||
struct mptcp_subflow_context *subflow;
|
||||
struct sockaddr_storage addr;
|
||||
int remote_id = remote->id;
|
||||
int local_id = loc->id;
|
||||
struct socket *sf;
|
||||
struct sock *ssk;
|
||||
@@ -1107,10 +1108,11 @@ int __mptcp_subflow_connect(struct sock *sk, int ifindex,
|
||||
goto failed;
|
||||
|
||||
mptcp_crypto_key_sha(subflow->remote_key, &remote_token, NULL);
|
||||
pr_debug("msk=%p remote_token=%u local_id=%d", msk, remote_token,
|
||||
local_id);
|
||||
pr_debug("msk=%p remote_token=%u local_id=%d remote_id=%d", msk,
|
||||
remote_token, local_id, remote_id);
|
||||
subflow->remote_token = remote_token;
|
||||
subflow->local_id = local_id;
|
||||
subflow->remote_id = remote_id;
|
||||
subflow->request_join = 1;
|
||||
subflow->request_bkup = 1;
|
||||
mptcp_info2sockaddr(remote, &addr);
|
||||
@@ -1347,6 +1349,7 @@ static void subflow_ulp_clone(const struct request_sock *req,
|
||||
new_ctx->fully_established = 1;
|
||||
new_ctx->backup = subflow_req->backup;
|
||||
new_ctx->local_id = subflow_req->local_id;
|
||||
new_ctx->remote_id = subflow_req->remote_id;
|
||||
new_ctx->token = subflow_req->token;
|
||||
new_ctx->thmac = subflow_req->thmac;
|
||||
}
|
||||
|
||||
@@ -851,7 +851,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
|
||||
}
|
||||
|
||||
struct ctnetlink_filter {
|
||||
u_int32_t cta_flags;
|
||||
u8 family;
|
||||
|
||||
u_int32_t orig_flags;
|
||||
@@ -906,10 +905,6 @@ static int ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
|
||||
struct nf_conntrack_zone *zone,
|
||||
u_int32_t flags);
|
||||
|
||||
/* applied on filters */
|
||||
#define CTA_FILTER_F_CTA_MARK (1 << 0)
|
||||
#define CTA_FILTER_F_CTA_MARK_MASK (1 << 1)
|
||||
|
||||
static struct ctnetlink_filter *
|
||||
ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
|
||||
{
|
||||
@@ -930,14 +925,10 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
if (cda[CTA_MARK]) {
|
||||
filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
|
||||
filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK);
|
||||
|
||||
if (cda[CTA_MARK_MASK]) {
|
||||
if (cda[CTA_MARK_MASK])
|
||||
filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
|
||||
filter->cta_flags |= CTA_FILTER_FLAG(CTA_MARK_MASK);
|
||||
} else {
|
||||
else
|
||||
filter->mark.mask = 0xffffffff;
|
||||
}
|
||||
} else if (cda[CTA_MARK_MASK]) {
|
||||
err = -EINVAL;
|
||||
goto err_filter;
|
||||
@@ -1117,11 +1108,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK_MASK)) &&
|
||||
(ct->mark & filter->mark.mask) != filter->mark.val)
|
||||
goto ignore_entry;
|
||||
else if ((filter->cta_flags & CTA_FILTER_FLAG(CTA_MARK)) &&
|
||||
ct->mark != filter->mark.val)
|
||||
if ((ct->mark & filter->mark.mask) != filter->mark.val)
|
||||
goto ignore_entry;
|
||||
#endif
|
||||
|
||||
@@ -1404,7 +1391,8 @@ ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
||||
if (l3num != NFPROTO_IPV4 && l3num != NFPROTO_IPV6)
|
||||
return -EOPNOTSUPP;
|
||||
tuple->src.l3num = l3num;
|
||||
|
||||
if (flags & CTA_FILTER_FLAG(CTA_IP_DST) ||
|
||||
|
||||
@@ -565,6 +565,7 @@ static int nf_ct_netns_inet_get(struct net *net)
|
||||
int err;
|
||||
|
||||
err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
|
||||
@@ -575,6 +576,7 @@ static int nf_ct_netns_inet_get(struct net *net)
|
||||
err2:
|
||||
nf_ct_netns_put(net, NFPROTO_IPV4);
|
||||
err1:
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -684,6 +684,18 @@ nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct nftnl_skb_parms {
|
||||
bool report;
|
||||
};
|
||||
#define NFT_CB(skb) (*(struct nftnl_skb_parms*)&((skb)->cb))
|
||||
|
||||
static void nft_notify_enqueue(struct sk_buff *skb, bool report,
|
||||
struct list_head *notify_list)
|
||||
{
|
||||
NFT_CB(skb).report = report;
|
||||
list_add_tail(&skb->list, notify_list);
|
||||
}
|
||||
|
||||
static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -715,8 +727,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
|
||||
ctx->report, GFP_KERNEL);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -1468,8 +1479,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
|
||||
ctx->report, GFP_KERNEL);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -2807,8 +2817,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
|
||||
ctx->report, GFP_KERNEL);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -3837,8 +3846,7 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
|
||||
gfp_flags);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -4959,8 +4967,7 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
|
||||
GFP_KERNEL);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -6275,7 +6282,7 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
|
||||
nft_notify_enqueue(skb, report, &net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -7085,8 +7092,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
|
||||
goto err;
|
||||
}
|
||||
|
||||
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
|
||||
ctx->report, GFP_KERNEL);
|
||||
nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
|
||||
return;
|
||||
err:
|
||||
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
|
||||
@@ -7695,6 +7701,41 @@ static void nf_tables_commit_release(struct net *net)
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
}
|
||||
|
||||
static void nft_commit_notify(struct net *net, u32 portid)
|
||||
{
|
||||
struct sk_buff *batch_skb = NULL, *nskb, *skb;
|
||||
unsigned char *data;
|
||||
int len;
|
||||
|
||||
list_for_each_entry_safe(skb, nskb, &net->nft.notify_list, list) {
|
||||
if (!batch_skb) {
|
||||
new_batch:
|
||||
batch_skb = skb;
|
||||
len = NLMSG_GOODSIZE - skb->len;
|
||||
list_del(&skb->list);
|
||||
continue;
|
||||
}
|
||||
len -= skb->len;
|
||||
if (len > 0 && NFT_CB(skb).report == NFT_CB(batch_skb).report) {
|
||||
data = skb_put(batch_skb, skb->len);
|
||||
memcpy(data, skb->data, skb->len);
|
||||
list_del(&skb->list);
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
|
||||
NFT_CB(batch_skb).report, GFP_KERNEL);
|
||||
goto new_batch;
|
||||
}
|
||||
|
||||
if (batch_skb) {
|
||||
nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
|
||||
NFT_CB(batch_skb).report, GFP_KERNEL);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
|
||||
}
|
||||
|
||||
static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
||||
{
|
||||
struct nft_trans *trans, *next;
|
||||
@@ -7897,6 +7938,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
nft_commit_notify(net, NETLINK_CB(skb).portid);
|
||||
nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
|
||||
nf_tables_commit_release(net);
|
||||
|
||||
@@ -8721,6 +8763,7 @@ static int __net_init nf_tables_init_net(struct net *net)
|
||||
INIT_LIST_HEAD(&net->nft.tables);
|
||||
INIT_LIST_HEAD(&net->nft.commit_list);
|
||||
INIT_LIST_HEAD(&net->nft.module_list);
|
||||
INIT_LIST_HEAD(&net->nft.notify_list);
|
||||
mutex_init(&net->nft.commit_mutex);
|
||||
net->nft.base_seq = 1;
|
||||
net->nft.validate_state = NFT_VALIDATE_SKIP;
|
||||
@@ -8737,6 +8780,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
WARN_ON_ONCE(!list_empty(&net->nft.tables));
|
||||
WARN_ON_ONCE(!list_empty(&net->nft.module_list));
|
||||
WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
|
||||
}
|
||||
|
||||
static struct pernet_operations nf_tables_net_ops = {
|
||||
|
||||
@@ -147,11 +147,11 @@ nft_meta_get_eval_skugid(enum nft_meta_keys key,
|
||||
|
||||
switch (key) {
|
||||
case NFT_META_SKUID:
|
||||
*dest = from_kuid_munged(&init_user_ns,
|
||||
*dest = from_kuid_munged(sock_net(sk)->user_ns,
|
||||
sock->file->f_cred->fsuid);
|
||||
break;
|
||||
case NFT_META_SKGID:
|
||||
*dest = from_kgid_munged(&init_user_ns,
|
||||
*dest = from_kgid_munged(sock_net(sk)->user_ns,
|
||||
sock->file->f_cred->fsgid);
|
||||
break;
|
||||
default:
|
||||
|
||||
+11
-10
@@ -332,8 +332,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
||||
{
|
||||
struct qrtr_hdr_v1 *hdr;
|
||||
size_t len = skb->len;
|
||||
int rc = -ENODEV;
|
||||
int confirm_rx;
|
||||
int rc, confirm_rx;
|
||||
|
||||
confirm_rx = qrtr_tx_wait(node, to->sq_node, to->sq_port, type);
|
||||
if (confirm_rx < 0) {
|
||||
@@ -357,15 +356,17 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
|
||||
hdr->size = cpu_to_le32(len);
|
||||
hdr->confirm_rx = !!confirm_rx;
|
||||
|
||||
skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr));
|
||||
|
||||
mutex_lock(&node->ep_lock);
|
||||
if (node->ep)
|
||||
rc = node->ep->xmit(node->ep, skb);
|
||||
else
|
||||
kfree_skb(skb);
|
||||
mutex_unlock(&node->ep_lock);
|
||||
rc = skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr));
|
||||
|
||||
if (!rc) {
|
||||
mutex_lock(&node->ep_lock);
|
||||
rc = -ENODEV;
|
||||
if (node->ep)
|
||||
rc = node->ep->xmit(node->ep, skb);
|
||||
else
|
||||
kfree_skb(skb);
|
||||
mutex_unlock(&node->ep_lock);
|
||||
}
|
||||
/* Need to ensure that a subsequent message carries the otherwise lost
|
||||
* confirm_rx flag if we dropped this one */
|
||||
if (rc && confirm_rx)
|
||||
|
||||
+34
-10
@@ -436,6 +436,25 @@ static void tcf_ife_cleanup(struct tc_action *a)
|
||||
kfree_rcu(p, rcu);
|
||||
}
|
||||
|
||||
static int load_metalist(struct nlattr **tb, bool rtnl_held)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < max_metacnt; i++) {
|
||||
if (tb[i]) {
|
||||
void *val = nla_data(tb[i]);
|
||||
int len = nla_len(tb[i]);
|
||||
int rc;
|
||||
|
||||
rc = load_metaops_and_vet(i, val, len, rtnl_held);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
|
||||
bool exists, bool rtnl_held)
|
||||
{
|
||||
@@ -449,10 +468,6 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
|
||||
val = nla_data(tb[i]);
|
||||
len = nla_len(tb[i]);
|
||||
|
||||
rc = load_metaops_and_vet(i, val, len, rtnl_held);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
rc = add_metainfo(ife, i, val, len, exists);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -509,6 +524,21 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
if (tb[TCA_IFE_METALST]) {
|
||||
err = nla_parse_nested_deprecated(tb2, IFE_META_MAX,
|
||||
tb[TCA_IFE_METALST], NULL,
|
||||
NULL);
|
||||
if (err) {
|
||||
kfree(p);
|
||||
return err;
|
||||
}
|
||||
err = load_metalist(tb2, rtnl_held);
|
||||
if (err) {
|
||||
kfree(p);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
index = parm->index;
|
||||
err = tcf_idr_check_alloc(tn, &index, a, bind);
|
||||
if (err < 0) {
|
||||
@@ -570,15 +600,9 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
|
||||
}
|
||||
|
||||
if (tb[TCA_IFE_METALST]) {
|
||||
err = nla_parse_nested_deprecated(tb2, IFE_META_MAX,
|
||||
tb[TCA_IFE_METALST], NULL,
|
||||
NULL);
|
||||
if (err)
|
||||
goto metadata_parse_err;
|
||||
err = populate_metalist(ife, tb2, exists, rtnl_held);
|
||||
if (err)
|
||||
goto metadata_parse_err;
|
||||
|
||||
} else {
|
||||
/* if no passed metadata allow list or passed allow-all
|
||||
* then here we process by adding as many supported metadatum
|
||||
|
||||
@@ -156,6 +156,7 @@ tunnel_key_copy_vxlan_opt(const struct nlattr *nla, void *dst, int dst_len,
|
||||
struct vxlan_metadata *md = dst;
|
||||
|
||||
md->gbp = nla_get_u32(tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
|
||||
md->gbp &= VXLAN_GBP_MASK;
|
||||
}
|
||||
|
||||
return sizeof(struct vxlan_metadata);
|
||||
|
||||
@@ -1175,8 +1175,10 @@ static int fl_set_vxlan_opt(const struct nlattr *nla, struct fl_flow_key *key,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP])
|
||||
if (tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]) {
|
||||
md->gbp = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]);
|
||||
md->gbp &= VXLAN_GBP_MASK;
|
||||
}
|
||||
|
||||
return sizeof(*md);
|
||||
}
|
||||
@@ -1221,6 +1223,7 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
|
||||
}
|
||||
if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) {
|
||||
nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX];
|
||||
memset(&md->u, 0x00, sizeof(md->u));
|
||||
md->u.index = nla_get_be32(nla);
|
||||
}
|
||||
} else if (md->version == 2) {
|
||||
|
||||
+33
-15
@@ -1131,24 +1131,10 @@ EXPORT_SYMBOL(dev_activate);
|
||||
|
||||
static void qdisc_deactivate(struct Qdisc *qdisc)
|
||||
{
|
||||
bool nolock = qdisc->flags & TCQ_F_NOLOCK;
|
||||
|
||||
if (qdisc->flags & TCQ_F_BUILTIN)
|
||||
return;
|
||||
if (test_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state))
|
||||
return;
|
||||
|
||||
if (nolock)
|
||||
spin_lock_bh(&qdisc->seqlock);
|
||||
spin_lock_bh(qdisc_lock(qdisc));
|
||||
|
||||
set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
|
||||
|
||||
qdisc_reset(qdisc);
|
||||
|
||||
spin_unlock_bh(qdisc_lock(qdisc));
|
||||
if (nolock)
|
||||
spin_unlock_bh(&qdisc->seqlock);
|
||||
}
|
||||
|
||||
static void dev_deactivate_queue(struct net_device *dev,
|
||||
@@ -1165,6 +1151,30 @@ static void dev_deactivate_queue(struct net_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static void dev_reset_queue(struct net_device *dev,
|
||||
struct netdev_queue *dev_queue,
|
||||
void *_unused)
|
||||
{
|
||||
struct Qdisc *qdisc;
|
||||
bool nolock;
|
||||
|
||||
qdisc = dev_queue->qdisc_sleeping;
|
||||
if (!qdisc)
|
||||
return;
|
||||
|
||||
nolock = qdisc->flags & TCQ_F_NOLOCK;
|
||||
|
||||
if (nolock)
|
||||
spin_lock_bh(&qdisc->seqlock);
|
||||
spin_lock_bh(qdisc_lock(qdisc));
|
||||
|
||||
qdisc_reset(qdisc);
|
||||
|
||||
spin_unlock_bh(qdisc_lock(qdisc));
|
||||
if (nolock)
|
||||
spin_unlock_bh(&qdisc->seqlock);
|
||||
}
|
||||
|
||||
static bool some_qdisc_is_busy(struct net_device *dev)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -1213,12 +1223,20 @@ void dev_deactivate_many(struct list_head *head)
|
||||
dev_watchdog_down(dev);
|
||||
}
|
||||
|
||||
/* Wait for outstanding qdisc-less dev_queue_xmit calls.
|
||||
/* Wait for outstanding qdisc-less dev_queue_xmit calls or
|
||||
* outstanding qdisc enqueuing calls.
|
||||
* This is avoided if all devices are in dismantle phase :
|
||||
* Caller will call synchronize_net() for us
|
||||
*/
|
||||
synchronize_net();
|
||||
|
||||
list_for_each_entry(dev, head, close_list) {
|
||||
netdev_for_each_tx_queue(dev, dev_reset_queue, NULL);
|
||||
|
||||
if (dev_ingress_queue(dev))
|
||||
dev_reset_queue(dev, dev_ingress_queue(dev), NULL);
|
||||
}
|
||||
|
||||
/* Wait for outstanding qdisc_run calls. */
|
||||
list_for_each_entry(dev, head, close_list) {
|
||||
while (some_qdisc_is_busy(dev)) {
|
||||
|
||||
+17
-11
@@ -777,9 +777,11 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = {
|
||||
[TCA_TAPRIO_ATTR_TXTIME_DELAY] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
|
||||
static int fill_sched_entry(struct taprio_sched *q, struct nlattr **tb,
|
||||
struct sched_entry *entry,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
int min_duration = length_to_duration(q, ETH_ZLEN);
|
||||
u32 interval = 0;
|
||||
|
||||
if (tb[TCA_TAPRIO_SCHED_ENTRY_CMD])
|
||||
@@ -794,7 +796,10 @@ static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
|
||||
interval = nla_get_u32(
|
||||
tb[TCA_TAPRIO_SCHED_ENTRY_INTERVAL]);
|
||||
|
||||
if (interval == 0) {
|
||||
/* The interval should allow at least the minimum ethernet
|
||||
* frame to go out.
|
||||
*/
|
||||
if (interval < min_duration) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid interval for schedule entry");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -804,8 +809,9 @@ static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_sched_entry(struct nlattr *n, struct sched_entry *entry,
|
||||
int index, struct netlink_ext_ack *extack)
|
||||
static int parse_sched_entry(struct taprio_sched *q, struct nlattr *n,
|
||||
struct sched_entry *entry, int index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[TCA_TAPRIO_SCHED_ENTRY_MAX + 1] = { };
|
||||
int err;
|
||||
@@ -819,10 +825,10 @@ static int parse_sched_entry(struct nlattr *n, struct sched_entry *entry,
|
||||
|
||||
entry->index = index;
|
||||
|
||||
return fill_sched_entry(tb, entry, extack);
|
||||
return fill_sched_entry(q, tb, entry, extack);
|
||||
}
|
||||
|
||||
static int parse_sched_list(struct nlattr *list,
|
||||
static int parse_sched_list(struct taprio_sched *q, struct nlattr *list,
|
||||
struct sched_gate_list *sched,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@@ -847,7 +853,7 @@ static int parse_sched_list(struct nlattr *list,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = parse_sched_entry(n, entry, i, extack);
|
||||
err = parse_sched_entry(q, n, entry, i, extack);
|
||||
if (err < 0) {
|
||||
kfree(entry);
|
||||
return err;
|
||||
@@ -862,7 +868,7 @@ static int parse_sched_list(struct nlattr *list,
|
||||
return i;
|
||||
}
|
||||
|
||||
static int parse_taprio_schedule(struct nlattr **tb,
|
||||
static int parse_taprio_schedule(struct taprio_sched *q, struct nlattr **tb,
|
||||
struct sched_gate_list *new,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@@ -883,8 +889,8 @@ static int parse_taprio_schedule(struct nlattr **tb,
|
||||
new->cycle_time = nla_get_s64(tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]);
|
||||
|
||||
if (tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST])
|
||||
err = parse_sched_list(
|
||||
tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST], new, extack);
|
||||
err = parse_sched_list(q, tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST],
|
||||
new, extack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@@ -1473,7 +1479,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
|
||||
goto free_sched;
|
||||
}
|
||||
|
||||
err = parse_taprio_schedule(tb, new_admin, extack);
|
||||
err = parse_taprio_schedule(q, tb, new_admin, extack);
|
||||
if (err < 0)
|
||||
goto free_sched;
|
||||
|
||||
|
||||
+3
-6
@@ -9220,13 +9220,10 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
|
||||
static inline void sctp_copy_descendant(struct sock *sk_to,
|
||||
const struct sock *sk_from)
|
||||
{
|
||||
int ancestor_size = sizeof(struct inet_sock) +
|
||||
sizeof(struct sctp_sock) -
|
||||
offsetof(struct sctp_sock, pd_lobby);
|
||||
|
||||
if (sk_from->sk_family == PF_INET6)
|
||||
ancestor_size += sizeof(struct ipv6_pinfo);
|
||||
size_t ancestor_size = sizeof(struct inet_sock);
|
||||
|
||||
ancestor_size += sk_from->sk_prot->obj_size;
|
||||
ancestor_size -= offsetof(struct sctp_sock, pd_lobby);
|
||||
__inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -273,8 +273,8 @@ static struct tipc_member *tipc_group_find_node(struct tipc_group *grp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void tipc_group_add_to_tree(struct tipc_group *grp,
|
||||
struct tipc_member *m)
|
||||
static int tipc_group_add_to_tree(struct tipc_group *grp,
|
||||
struct tipc_member *m)
|
||||
{
|
||||
u64 nkey, key = (u64)m->node << 32 | m->port;
|
||||
struct rb_node **n, *parent = NULL;
|
||||
@@ -291,10 +291,11 @@ static void tipc_group_add_to_tree(struct tipc_group *grp,
|
||||
else if (key > nkey)
|
||||
n = &(*n)->rb_right;
|
||||
else
|
||||
return;
|
||||
return -EEXIST;
|
||||
}
|
||||
rb_link_node(&m->tree_node, parent, n);
|
||||
rb_insert_color(&m->tree_node, &grp->members);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
|
||||
@@ -302,6 +303,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
|
||||
u32 instance, int state)
|
||||
{
|
||||
struct tipc_member *m;
|
||||
int ret;
|
||||
|
||||
m = kzalloc(sizeof(*m), GFP_ATOMIC);
|
||||
if (!m)
|
||||
@@ -314,8 +316,12 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
|
||||
m->port = port;
|
||||
m->instance = instance;
|
||||
m->bc_acked = grp->bc_snd_nxt - 1;
|
||||
ret = tipc_group_add_to_tree(grp, m);
|
||||
if (ret < 0) {
|
||||
kfree(m);
|
||||
return NULL;
|
||||
}
|
||||
grp->member_cnt++;
|
||||
tipc_group_add_to_tree(grp, m);
|
||||
tipc_nlist_add(&grp->dests, m->node);
|
||||
m->state = state;
|
||||
return m;
|
||||
|
||||
+2
-1
@@ -532,7 +532,8 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
|
||||
* tipc_link_bc_create - create new link to be used for broadcast
|
||||
* @net: pointer to associated network namespace
|
||||
* @mtu: mtu to be used initially if no peers
|
||||
* @window: send window to be used
|
||||
* @min_win: minimal send window to be used by link
|
||||
* @max_win: maximal send window to be used by link
|
||||
* @inputq: queue to put messages ready for delivery
|
||||
* @namedq: queue to put binding table update messages ready for delivery
|
||||
* @link: return value, pointer to put the created link
|
||||
|
||||
+2
-1
@@ -150,7 +150,8 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
|
||||
if (fragid == FIRST_FRAGMENT) {
|
||||
if (unlikely(head))
|
||||
goto err;
|
||||
if (unlikely(skb_unclone(frag, GFP_ATOMIC)))
|
||||
frag = skb_unshare(frag, GFP_ATOMIC);
|
||||
if (unlikely(!frag))
|
||||
goto err;
|
||||
head = *headbuf = frag;
|
||||
*buf = NULL;
|
||||
|
||||
+1
-4
@@ -2771,10 +2771,7 @@ static int tipc_shutdown(struct socket *sock, int how)
|
||||
|
||||
trace_tipc_sk_shutdown(sk, NULL, TIPC_DUMP_ALL, " ");
|
||||
__tipc_shutdown(sock, TIPC_CONN_SHUTDOWN);
|
||||
if (tipc_sk_type_connectionless(sk))
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
else
|
||||
sk->sk_shutdown = SEND_SHUTDOWN;
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
|
||||
if (sk->sk_state == TIPC_DISCONNECTING) {
|
||||
/* Discard any unreceived messages */
|
||||
|
||||
@@ -217,6 +217,7 @@ config LIB80211_CRYPT_WEP
|
||||
|
||||
config LIB80211_CRYPT_CCMP
|
||||
tristate
|
||||
select CRYPTO
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CCM
|
||||
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
|
||||
/* see 802.11ax D6.1 27.3.23.2 */
|
||||
if (chan == 2)
|
||||
return MHZ_TO_KHZ(5935);
|
||||
if (chan <= 253)
|
||||
if (chan <= 233)
|
||||
return MHZ_TO_KHZ(5950 + chan * 5);
|
||||
break;
|
||||
case NL80211_BAND_60GHZ:
|
||||
|
||||
+8
-9
@@ -303,10 +303,10 @@ static int xdp_umem_account_pages(struct xdp_umem *umem)
|
||||
|
||||
static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
|
||||
{
|
||||
u32 npgs_rem, chunk_size = mr->chunk_size, headroom = mr->headroom;
|
||||
bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
|
||||
u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
|
||||
u64 npgs, addr = mr->addr, size = mr->len;
|
||||
unsigned int chunks, chunks_per_page;
|
||||
unsigned int chunks, chunks_rem;
|
||||
int err;
|
||||
|
||||
if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
|
||||
@@ -336,19 +336,18 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
|
||||
if ((addr + size) < addr)
|
||||
return -EINVAL;
|
||||
|
||||
npgs = size >> PAGE_SHIFT;
|
||||
npgs = div_u64_rem(size, PAGE_SIZE, &npgs_rem);
|
||||
if (npgs_rem)
|
||||
npgs++;
|
||||
if (npgs > U32_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
chunks = (unsigned int)div_u64(size, chunk_size);
|
||||
chunks = (unsigned int)div_u64_rem(size, chunk_size, &chunks_rem);
|
||||
if (chunks == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!unaligned_chunks) {
|
||||
chunks_per_page = PAGE_SIZE / chunk_size;
|
||||
if (chunks < chunks_per_page || chunks % chunks_per_page)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!unaligned_chunks && chunks_rem)
|
||||
return -EINVAL;
|
||||
|
||||
if (headroom >= chunk_size - XDP_PACKET_HEADROOM)
|
||||
return -EINVAL;
|
||||
|
||||
Reference in New Issue
Block a user