Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux

This commit is contained in:
David S. Miller
2016-03-19 21:05:24 -04:00
6527 changed files with 314251 additions and 168833 deletions

View File

@@ -75,6 +75,8 @@
#define LOWPAN_IPHC_MAX_HC_BUF_LEN (sizeof(struct ipv6hdr) + \
LOWPAN_IPHC_MAX_HEADER_LEN + \
LOWPAN_NHC_MAX_HDR_LEN)
/* SCI/DCI is 4 bit width, so we have maximum 16 entries */
#define LOWPAN_IPHC_CTX_TABLE_SIZE (1 << 4)
#define LOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
#define LOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */
@@ -98,9 +100,39 @@ enum lowpan_lltypes {
LOWPAN_LLTYPE_IEEE802154,
};
enum lowpan_iphc_ctx_flags {
LOWPAN_IPHC_CTX_FLAG_ACTIVE,
LOWPAN_IPHC_CTX_FLAG_COMPRESSION,
};
struct lowpan_iphc_ctx {
u8 id;
struct in6_addr pfx;
u8 plen;
unsigned long flags;
};
struct lowpan_iphc_ctx_table {
spinlock_t lock;
const struct lowpan_iphc_ctx_ops *ops;
struct lowpan_iphc_ctx table[LOWPAN_IPHC_CTX_TABLE_SIZE];
};
static inline bool lowpan_iphc_ctx_is_active(const struct lowpan_iphc_ctx *ctx)
{
return test_bit(LOWPAN_IPHC_CTX_FLAG_ACTIVE, &ctx->flags);
}
static inline bool
lowpan_iphc_ctx_is_compression(const struct lowpan_iphc_ctx *ctx)
{
return test_bit(LOWPAN_IPHC_CTX_FLAG_COMPRESSION, &ctx->flags);
}
struct lowpan_priv {
enum lowpan_lltypes lltype;
struct dentry *iface_debugfs;
struct lowpan_iphc_ctx_table ctx;
/* must be last */
u8 priv[0] __aligned(sizeof(void *));

View File

@@ -7,6 +7,8 @@
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
struct tcf_common {
struct hlist_node tcfc_head;
@@ -65,11 +67,6 @@ static inline int tcf_hashinfo_init(struct tcf_hashinfo *hf, unsigned int mask)
return 0;
}
static inline void tcf_hashinfo_destroy(struct tcf_hashinfo *hf)
{
kfree(hf->htab);
}
/* Update lastuse only if needed, to avoid dirtying a cache line.
* We use a temp variable to avoid fetching jiffies twice.
*/
@@ -81,42 +78,76 @@ static inline void tcf_lastuse_update(struct tcf_t *tm)
tm->lastuse = now;
}
#ifdef CONFIG_NET_CLS_ACT
#define ACT_P_CREATED 1
#define ACT_P_DELETED 1
struct tc_action {
void *priv;
const struct tc_action_ops *ops;
__u32 type; /* for backward compat(TCA_OLD_COMPAT) */
__u32 order;
struct list_head list;
struct tcf_hashinfo *hinfo;
};
#ifdef CONFIG_NET_CLS_ACT
#define ACT_P_CREATED 1
#define ACT_P_DELETED 1
struct tc_action_ops {
struct list_head head;
struct tcf_hashinfo *hinfo;
char kind[IFNAMSIZ];
__u32 type; /* TBD to match kind */
struct module *owner;
int (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void (*cleanup)(struct tc_action *, int bind);
int (*lookup)(struct tc_action *, u32);
int (*lookup)(struct net *, struct tc_action *, u32);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action *act, int ovr,
int bind);
int (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int, struct tc_action *);
};
int tcf_hash_search(struct tc_action *a, u32 index);
u32 tcf_hash_new_index(struct tcf_hashinfo *hinfo);
int tcf_hash_check(u32 index, struct tc_action *a, int bind);
int tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a,
int size, int bind, bool cpustats);
struct tc_action_net {
struct tcf_hashinfo *hinfo;
const struct tc_action_ops *ops;
};
static inline
int tc_action_net_init(struct tc_action_net *tn, const struct tc_action_ops *ops,
unsigned int mask)
{
int err = 0;
tn->hinfo = kmalloc(sizeof(*tn->hinfo), GFP_KERNEL);
if (!tn->hinfo)
return -ENOMEM;
tn->ops = ops;
err = tcf_hashinfo_init(tn->hinfo, mask);
if (err)
kfree(tn->hinfo);
return err;
}
void tcf_hashinfo_destroy(const struct tc_action_ops *ops,
struct tcf_hashinfo *hinfo);
static inline void tc_action_net_exit(struct tc_action_net *tn)
{
tcf_hashinfo_destroy(tn->ops, tn->hinfo);
}
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
struct netlink_callback *cb, int type,
struct tc_action *a);
int tcf_hash_search(struct tc_action_net *tn, struct tc_action *a, u32 index);
u32 tcf_hash_new_index(struct tc_action_net *tn);
int tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action *a,
int bind);
int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
struct tc_action *a, int size, int bind, bool cpustats);
void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
void tcf_hash_insert(struct tc_action *a);
void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);
int __tcf_hash_release(struct tc_action *a, bool bind, bool strict);
@@ -125,8 +156,8 @@ static inline int tcf_hash_release(struct tc_action *a, bool bind)
return __tcf_hash_release(a, bind, false);
}
int tcf_register_action(struct tc_action_ops *a, unsigned int mask);
int tcf_unregister_action(struct tc_action_ops *a);
int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
int tcf_unregister_action(struct tc_action_ops *a, struct pernet_operations *ops);
int tcf_action_destroy(struct list_head *actions, int bind);
int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions,
struct tcf_result *res);
@@ -140,5 +171,16 @@ int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
#define tc_no_actions(_exts) \
(list_empty(&(_exts)->actions))
#define tc_for_each_action(_a, _exts) \
list_for_each_entry(a, &(_exts)->actions, list)
#else /* CONFIG_NET_CLS_ACT */
#define tc_no_actions(_exts) true
#define tc_for_each_action(_a, _exts) while (0)
#endif /* CONFIG_NET_CLS_ACT */
#endif

View File

@@ -87,6 +87,8 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
u32 banned_flags);
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
u32 banned_flags);
int ipv4_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
bool match_wildcard);
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
bool match_wildcard);
void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);

View File

@@ -233,6 +233,7 @@ enum {
HCI_SC_ENABLED,
HCI_SC_ONLY,
HCI_PRIVACY,
HCI_LIMITED_PRIVACY,
HCI_RPA_EXPIRED,
HCI_RPA_RESOLVING,
HCI_HS_ENABLED,

View File

@@ -25,6 +25,7 @@
#ifndef __HCI_CORE_H
#define __HCI_CORE_H
#include <linux/leds.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_sock.h>
@@ -396,6 +397,8 @@ struct hci_dev {
struct delayed_work rpa_expired;
bdaddr_t rpa;
struct led_trigger *power_led;
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);

View File

@@ -306,5 +306,6 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond);
void bond_3ad_update_lacp_rate(struct bonding *bond);
void bond_3ad_update_ad_actor_settings(struct bonding *bond);
#endif /* _NET_BOND_3AD_H */

View File

@@ -215,6 +215,7 @@ struct bonding {
* ALB mode (6) - to sync the use and modifications of its hash table
*/
spinlock_t mode_lock;
spinlock_t stats_lock;
u8 send_peer_notif;
u8 igmp_retrans;
#ifdef CONFIG_PROC_FS

View File

@@ -712,6 +712,8 @@ struct cfg80211_acl_data {
* @p2p_opp_ps: P2P opportunistic PS
* @acl: ACL configuration used by the drivers which has support for
* MAC address based access control
* @pbss: If set, start as a PCP instead of AP. Relevant for DMG
* networks.
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -730,6 +732,7 @@ struct cfg80211_ap_settings {
u8 p2p_ctwindow;
bool p2p_opp_ps;
const struct cfg80211_acl_data *acl;
bool pbss;
};
/**
@@ -1888,6 +1891,8 @@ struct cfg80211_ibss_params {
* @ht_capa_mask: The bits of ht_capa which are to be used.
* @vht_capa: VHT Capability overrides
* @vht_capa_mask: The bits of vht_capa which are to be used.
* @pbss: if set, connect to a PCP instead of AP. Valid for DMG
* networks.
*/
struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -1910,6 +1915,7 @@ struct cfg80211_connect_params {
struct ieee80211_ht_cap ht_capa_mask;
struct ieee80211_vht_cap vht_capa;
struct ieee80211_vht_cap vht_capa_mask;
bool pbss;
};
/**
@@ -3489,6 +3495,7 @@ struct cfg80211_cached_keys;
* registered for unexpected class 3 frames (AP mode)
* @conn: (private) cfg80211 software SME connection state machine data
* @connect_keys: (private) keys to set after connection is established
* @conn_bss_type: connecting/connected BSS type
* @ibss_fixed: (private) IBSS is using fixed BSSID
* @ibss_dfs_possible: (private) IBSS may change to a DFS channel
* @event_list: (private) list for internal event processing
@@ -3519,6 +3526,7 @@ struct wireless_dev {
u8 ssid_len, mesh_id_len, mesh_id_up_len;
struct cfg80211_conn *conn;
struct cfg80211_cached_keys *connect_keys;
enum ieee80211_bss_type conn_bss_type;
struct list_head event_list;
spinlock_t event_lock;

View File

@@ -88,8 +88,11 @@ static inline __wsum
csum_block_add(__wsum csum, __wsum csum2, int offset)
{
u32 sum = (__force u32)csum2;
if (offset&1)
sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
/* rotate sum to align it with a 16b boundary */
if (offset & 1)
sum = ror32(sum, 8);
return csum_add(csum, (__force __wsum)sum);
}
@@ -102,10 +105,7 @@ csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len)
static inline __wsum
csum_block_sub(__wsum csum, __wsum csum2, int offset)
{
u32 sum = (__force u32)csum2;
if (offset&1)
sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF);
return csum_sub(csum, (__force __wsum)sum);
return csum_block_add(csum, ~csum2, offset);
}
static inline __wsum csum_unfold(__sum16 n)
@@ -120,6 +120,11 @@ static inline __wsum csum_partial_ext(const void *buff, int len, __wsum sum)
#define CSUM_MANGLED_0 ((__force __sum16)0xffff)
static inline void csum_replace_by_diff(__sum16 *sum, __wsum diff)
{
*sum = csum_fold(csum_add(diff, ~csum_unfold(*sum)));
}
static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
{
__wsum tmp = csum_sub(~csum_unfold(*sum), (__force __wsum)from);

View File

@@ -162,12 +162,14 @@ struct codel_vars {
* struct codel_stats - contains codel shared variables and stats
* @maxpacket: largest packet we've seen so far
* @drop_count: temp count of dropped packets in dequeue()
* @drop_len: bytes of dropped packets in dequeue()
* ecn_mark: number of packets we ECN marked instead of dropping
* ce_mark: number of packets CE marked because sojourn time was above ce_threshold
*/
struct codel_stats {
u32 maxpacket;
u32 drop_count;
u32 drop_len;
u32 ecn_mark;
u32 ce_mark;
};
@@ -308,6 +310,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
vars->rec_inv_sqrt);
goto end;
}
stats->drop_len += qdisc_pkt_len(skb);
qdisc_drop(skb, sch);
stats->drop_count++;
skb = dequeue_func(vars, sch);
@@ -330,6 +333,7 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
if (params->ecn && INET_ECN_set_ce(skb)) {
stats->ecn_mark++;
} else {
stats->drop_len += qdisc_pkt_len(skb);
qdisc_drop(skb, sch);
stats->drop_count++;

140
include/net/devlink.h Normal file
View File

@@ -0,0 +1,140 @@
/*
* include/net/devlink.h - Network physical device Netlink interface
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _NET_DEVLINK_H_
#define _NET_DEVLINK_H_
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/gfp.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <uapi/linux/devlink.h>
struct devlink_ops;
struct devlink {
struct list_head list;
struct list_head port_list;
const struct devlink_ops *ops;
struct device *dev;
possible_net_t _net;
char priv[0] __aligned(NETDEV_ALIGN);
};
struct devlink_port {
struct list_head list;
struct devlink *devlink;
unsigned index;
bool registered;
enum devlink_port_type type;
enum devlink_port_type desired_type;
void *type_dev;
bool split;
u32 split_group;
};
struct devlink_ops {
size_t priv_size;
int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type);
int (*port_split)(struct devlink *devlink, unsigned int port_index,
unsigned int count);
int (*port_unsplit)(struct devlink *devlink, unsigned int port_index);
};
static inline void *devlink_priv(struct devlink *devlink)
{
BUG_ON(!devlink);
return &devlink->priv;
}
static inline struct devlink *priv_to_devlink(void *priv)
{
BUG_ON(!priv);
return container_of(priv, struct devlink, priv);
}
struct ib_device;
#if IS_ENABLED(CONFIG_NET_DEVLINK)
struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size);
int devlink_register(struct devlink *devlink, struct device *dev);
void devlink_unregister(struct devlink *devlink);
void devlink_free(struct devlink *devlink);
int devlink_port_register(struct devlink *devlink,
struct devlink_port *devlink_port,
unsigned int port_index);
void devlink_port_unregister(struct devlink_port *devlink_port);
void devlink_port_type_eth_set(struct devlink_port *devlink_port,
struct net_device *netdev);
void devlink_port_type_ib_set(struct devlink_port *devlink_port,
struct ib_device *ibdev);
void devlink_port_type_clear(struct devlink_port *devlink_port);
void devlink_port_split_set(struct devlink_port *devlink_port,
u32 split_group);
#else
static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
size_t priv_size)
{
return kzalloc(sizeof(struct devlink) + priv_size, GFP_KERNEL);
}
static inline int devlink_register(struct devlink *devlink, struct device *dev)
{
return 0;
}
static inline void devlink_unregister(struct devlink *devlink)
{
}
static inline void devlink_free(struct devlink *devlink)
{
kfree(devlink);
}
static inline int devlink_port_register(struct devlink *devlink,
struct devlink_port *devlink_port,
unsigned int port_index)
{
return 0;
}
static inline void devlink_port_unregister(struct devlink_port *devlink_port)
{
}
static inline void devlink_port_type_eth_set(struct devlink_port *devlink_port,
struct net_device *netdev)
{
}
static inline void devlink_port_type_ib_set(struct devlink_port *devlink_port,
struct ib_device *ibdev)
{
}
static inline void devlink_port_type_clear(struct devlink_port *devlink_port)
{
}
static inline void devlink_port_split_set(struct devlink_port *devlink_port,
u32 split_group)
{
}
#endif
#endif /* _NET_DEVLINK_H_ */

View File

@@ -296,16 +296,17 @@ struct dsa_switch_driver {
/*
* Bridge integration
*/
int (*port_join_bridge)(struct dsa_switch *ds, int port,
u32 br_port_mask);
int (*port_leave_bridge)(struct dsa_switch *ds, int port,
u32 br_port_mask);
int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct net_device *bridge);
void (*port_bridge_leave)(struct dsa_switch *ds, int port);
int (*port_stp_update)(struct dsa_switch *ds, int port,
u8 state);
/*
* VLAN support
*/
int (*port_vlan_filtering)(struct dsa_switch *ds, int port,
bool vlan_filtering);
int (*port_vlan_prepare)(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_vlan *vlan,
struct switchdev_trans *trans);
@@ -314,9 +315,9 @@ struct dsa_switch_driver {
struct switchdev_trans *trans);
int (*port_vlan_del)(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_vlan *vlan);
int (*port_pvid_get)(struct dsa_switch *ds, int port, u16 *pvid);
int (*vlan_getnext)(struct dsa_switch *ds, u16 *vid,
unsigned long *ports, unsigned long *untagged);
int (*port_vlan_dump)(struct dsa_switch *ds, int port,
struct switchdev_obj_port_vlan *vlan,
int (*cb)(struct switchdev_obj *obj));
/*
* Forwarding database

View File

@@ -398,6 +398,18 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
__skb_tunnel_rx(skb, dev, net);
}
static inline u32 dst_tclassid(const struct sk_buff *skb)
{
#ifdef CONFIG_IP_ROUTE_CLASSID
const struct dst_entry *dst;
dst = skb_dst(skb);
if (dst)
return dst->tclassid;
#endif
return 0;
}
int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
static inline int dst_discard(struct sk_buff *skb)
{

97
include/net/dst_cache.h Normal file
View File

@@ -0,0 +1,97 @@
#ifndef _NET_DST_CACHE_H
#define _NET_DST_CACHE_H
#include <linux/jiffies.h>
#include <net/dst.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ip6_fib.h>
#endif
struct dst_cache {
struct dst_cache_pcpu __percpu *cache;
unsigned long reset_ts;
};
/**
* dst_cache_get - perform cache lookup
* @dst_cache: the cache
*
* The caller should use dst_cache_get_ip4() if it need to retrieve the
* source address to be used when xmitting to the cached dst.
* local BH must be disabled.
*/
struct dst_entry *dst_cache_get(struct dst_cache *dst_cache);
/**
* dst_cache_get_ip4 - perform cache lookup and fetch ipv4 source address
* @dst_cache: the cache
* @saddr: return value for the retrieved source address
*
* local BH must be disabled.
*/
struct rtable *dst_cache_get_ip4(struct dst_cache *dst_cache, __be32 *saddr);
/**
* dst_cache_set_ip4 - store the ipv4 dst into the cache
* @dst_cache: the cache
* @dst: the entry to be cached
* @saddr: the source address to be stored inside the cache
*
* local BH must be disabled.
*/
void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst,
__be32 saddr);
#if IS_ENABLED(CONFIG_IPV6)
/**
* dst_cache_set_ip6 - store the ipv6 dst into the cache
* @dst_cache: the cache
* @dst: the entry to be cached
* @saddr: the source address to be stored inside the cache
*
* local BH must be disabled.
*/
void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
const struct in6_addr *addr);
/**
* dst_cache_get_ip6 - perform cache lookup and fetch ipv6 source address
* @dst_cache: the cache
* @saddr: return value for the retrieved source address
*
* local BH must be disabled.
*/
struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache,
struct in6_addr *saddr);
#endif
/**
* dst_cache_reset - invalidate the cache contents
* @dst_cache: the cache
*
* This do not free the cached dst to avoid races and contentions.
* the dst will be freed on later cache lookup.
*/
static inline void dst_cache_reset(struct dst_cache *dst_cache)
{
dst_cache->reset_ts = jiffies;
}
/**
* dst_cache_init - initialize the cache, allocating the required storage
* @dst_cache: the cache
* @gfp: allocation flags
*/
int dst_cache_init(struct dst_cache *dst_cache, gfp_t gfp);
/**
* dst_cache_destroy - empty the cache and free the allocated storage
* @dst_cache: the cache
*
* No synchronization is enforced: it must be called only when the cache
* is unsed.
*/
void dst_cache_destroy(struct dst_cache *dst_cache);
#endif

View File

@@ -62,6 +62,7 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
sizeof(a->u.tun_info) + a->u.tun_info.options_len);
}
void metadata_dst_free(struct metadata_dst *);
struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);
@@ -125,7 +126,7 @@ static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
ip_tunnel_key_init(&tun_dst->u.tun_info.key,
iph->saddr, iph->daddr, iph->tos, iph->ttl,
0, 0, tunnel_id, flags);
0, 0, 0, tunnel_id, flags);
return tun_dst;
}
@@ -151,8 +152,11 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
info->key.u.ipv6.src = ip6h->saddr;
info->key.u.ipv6.dst = ip6h->daddr;
info->key.tos = ipv6_get_dsfield(ip6h);
info->key.ttl = ip6h->hop_limit;
info->key.label = ip6_flowlabel(ip6h);
return tun_dst;
}

View File

@@ -184,4 +184,17 @@ static inline bool flow_keys_have_l4(struct flow_keys *keys)
u32 flow_hash_from_keys(struct flow_keys *keys);
static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
enum flow_dissector_key_id key_id)
{
return flow_dissector->used_keys & (1 << key_id);
}
static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
enum flow_dissector_key_id key_id,
void *target_container)
{
return ((char *)target_container) + flow_dissector->offset[key_id];
}
#endif

View File

@@ -83,7 +83,6 @@ struct genl_family {
* @attrs: netlink attributes
* @_net: network namespace
* @user_ptr: user pointers
* @dst_sk: destination socket
*/
struct genl_info {
u32 snd_seq;
@@ -94,7 +93,6 @@ struct genl_info {
struct nlattr ** attrs;
possible_net_t _net;
void * user_ptr[2];
struct sock * dst_sk;
};
static inline struct net *genl_info_net(struct genl_info *info)
@@ -188,8 +186,6 @@ int genl_unregister_family(struct genl_family *family);
void genl_notify(struct genl_family *family, struct sk_buff *skb,
struct genl_info *info, u32 group, gfp_t flags);
struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
gfp_t flags);
void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
struct genl_family *family, int flags, u8 cmd);

28
include/net/hwbm.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef _HWBM_H
#define _HWBM_H
struct hwbm_pool {
/* Capacity of the pool */
int size;
/* Size of the buffers managed */
int frag_size;
/* Number of buffers currently used by this pool */
int buf_num;
/* constructor called during alocation */
int (*construct)(struct hwbm_pool *bm_pool, void *buf);
/* protect acces to the buffer counter*/
spinlock_t lock;
/* private data */
void *priv;
};
#ifdef CONFIG_HWBM
void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf);
int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp);
int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp);
#else
void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {}
int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) { return 0; }
int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
{ return 0; }
#endif /* CONFIG_HWBM */
#endif /* _HWBM_H */

View File

@@ -53,6 +53,7 @@ struct sock *__inet6_lookup_established(struct net *net,
struct sock *inet6_lookup_listener(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
@@ -60,6 +61,7 @@ struct sock *inet6_lookup_listener(struct net *net,
static inline struct sock *__inet6_lookup(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
@@ -71,12 +73,12 @@ static inline struct sock *__inet6_lookup(struct net *net,
if (sk)
return sk;
return inet6_lookup_listener(net, hashinfo, saddr, sport,
return inet6_lookup_listener(net, hashinfo, skb, doff, saddr, sport,
daddr, hnum, dif);
}
static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
struct sk_buff *skb,
struct sk_buff *skb, int doff,
const __be16 sport,
const __be16 dport,
int iif)
@@ -86,16 +88,19 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
if (sk)
return sk;
return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
&ipv6_hdr(skb)->saddr, sport,
return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
doff, &ipv6_hdr(skb)->saddr, sport,
&ipv6_hdr(skb)->daddr, ntohs(dport),
iif);
}
struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif);
int inet6_hash(struct sock *sk);
#endif /* IS_ENABLED(CONFIG_IPV6) */
#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \

View File

@@ -13,6 +13,7 @@ struct netns_frags {
int timeout;
int high_thresh;
int low_thresh;
int max_dist;
};
/**

View File

@@ -207,12 +207,16 @@ void inet_hashinfo_init(struct inet_hashinfo *h);
bool inet_ehash_insert(struct sock *sk, struct sock *osk);
bool inet_ehash_nolisten(struct sock *sk, struct sock *osk);
void __inet_hash(struct sock *sk, struct sock *osk);
void inet_hash(struct sock *sk);
int __inet_hash(struct sock *sk, struct sock *osk,
int (*saddr_same)(const struct sock *sk1,
const struct sock *sk2,
bool match_wildcard));
int inet_hash(struct sock *sk);
void inet_unhash(struct sock *sk);
struct sock *__inet_lookup_listener(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const __be32 saddr, const __be16 sport,
const __be32 daddr,
const unsigned short hnum,
@@ -220,10 +224,11 @@ struct sock *__inet_lookup_listener(struct net *net,
static inline struct sock *inet_lookup_listener(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
__be32 saddr, __be16 sport,
__be32 daddr, __be16 dport, int dif)
{
return __inet_lookup_listener(net, hashinfo, saddr, sport,
return __inet_lookup_listener(net, hashinfo, skb, doff, saddr, sport,
daddr, ntohs(dport), dif);
}
@@ -299,6 +304,7 @@ static inline struct sock *
static inline struct sock *__inet_lookup(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
@@ -307,12 +313,13 @@ static inline struct sock *__inet_lookup(struct net *net,
struct sock *sk = __inet_lookup_established(net, hashinfo,
saddr, sport, daddr, hnum, dif);
return sk ? : __inet_lookup_listener(net, hashinfo, saddr, sport,
daddr, hnum, dif);
return sk ? : __inet_lookup_listener(net, hashinfo, skb, doff, saddr,
sport, daddr, hnum, dif);
}
static inline struct sock *inet_lookup(struct net *net,
struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
@@ -320,7 +327,8 @@ static inline struct sock *inet_lookup(struct net *net,
struct sock *sk;
local_bh_disable();
sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
sk = __inet_lookup(net, hashinfo, skb, doff, saddr, sport, daddr,
dport, dif);
local_bh_enable();
return sk;
@@ -328,6 +336,7 @@ static inline struct sock *inet_lookup(struct net *net,
static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
struct sk_buff *skb,
int doff,
const __be16 sport,
const __be16 dport)
{
@@ -337,8 +346,8 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
if (sk)
return sk;
else
return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
iph->saddr, sport,
return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
doff, iph->saddr, sport,
iph->daddr, dport, inet_iif(skb));
}

View File

@@ -240,17 +240,13 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
}
#endif
__be32 inet_current_timestamp(void);
/* From inetpeer.c */
extern int inet_peer_threshold;
extern int inet_peer_minttl;
extern int inet_peer_maxttl;
/* From ip_input.c */
extern int sysctl_ip_early_demux;
/* From ip_output.c */
extern int sysctl_ip_dynaddr;
void ipfrag_init(void);
void ip_static_sysctl_init(void);

View File

@@ -37,8 +37,7 @@
#ifndef _HAVE_ARCH_IPV6_CSUM
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum csum);
__u32 len, __u8 proto, __wsum csum);
#endif
static inline __wsum ip6_compute_pseudo(struct sk_buff *skb, int proto)

View File

@@ -6,6 +6,7 @@
#include <linux/if_tunnel.h>
#include <linux/ip6_tunnel.h>
#include <net/ip_tunnels.h>
#include <net/dst_cache.h>
#define IP6TUNNEL_ERR_TIMEO (30*HZ)
@@ -33,12 +34,6 @@ struct __ip6_tnl_parm {
__be32 o_key;
};
struct ip6_tnl_dst {
seqlock_t lock;
struct dst_entry __rcu *dst;
u32 cookie;
};
/* IPv6 tunnel */
struct ip6_tnl {
struct ip6_tnl __rcu *next; /* next tunnel in list */
@@ -46,7 +41,7 @@ struct ip6_tnl {
struct net *net; /* netns for packet i/o */
struct __ip6_tnl_parm parms; /* tunnel configuration parameters */
struct flowi fl; /* flowi template for xmit */
struct ip6_tnl_dst __percpu *dst_cache; /* cached dst */
struct dst_cache dst_cache; /* cached dst */
int err_count;
unsigned long err_time;
@@ -66,11 +61,6 @@ struct ipv6_tlv_tnl_enc_lim {
__u8 encap_limit; /* tunnel encapsulation limit */
} __packed;
struct dst_entry *ip6_tnl_dst_get(struct ip6_tnl *t);
int ip6_tnl_dst_init(struct ip6_tnl *t);
void ip6_tnl_dst_destroy(struct ip6_tnl *t);
void ip6_tnl_dst_reset(struct ip6_tnl *t);
void ip6_tnl_dst_set(struct ip6_tnl *t, struct dst_entry *dst);
int ip6_tnl_rcv_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,
const struct in6_addr *raddr);
int ip6_tnl_xmit_ctl(struct ip6_tnl *t, const struct in6_addr *laddr,

View File

@@ -7,12 +7,15 @@
#include <linux/socket.h>
#include <linux/types.h>
#include <linux/u64_stats_sync.h>
#include <linux/bitops.h>
#include <net/dsfield.h>
#include <net/gro_cells.h>
#include <net/inet_ecn.h>
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
#include <net/lwtunnel.h>
#include <net/dst_cache.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6.h>
@@ -47,6 +50,7 @@ struct ip_tunnel_key {
__be16 tun_flags;
u8 tos; /* TOS for IPv4, TC for IPv6 */
u8 ttl; /* TTL for IPv4, HL for IPv6 */
__be32 label; /* Flow Label for IPv6 */
__be16 tp_src;
__be16 tp_dst;
};
@@ -55,8 +59,16 @@ struct ip_tunnel_key {
#define IP_TUNNEL_INFO_TX 0x01 /* represents tx tunnel parameters */
#define IP_TUNNEL_INFO_IPV6 0x02 /* key contains IPv6 addresses */
/* Maximum tunnel options length. */
#define IP_TUNNEL_OPTS_MAX \
GENMASK((FIELD_SIZEOF(struct ip_tunnel_info, \
options_len) * BITS_PER_BYTE) - 1, 0)
struct ip_tunnel_info {
struct ip_tunnel_key key;
#ifdef CONFIG_DST_CACHE
struct dst_cache dst_cache;
#endif
u8 options_len;
u8 mode;
};
@@ -85,11 +97,6 @@ struct ip_tunnel_prl_entry {
struct rcu_head rcu_head;
};
struct ip_tunnel_dst {
struct dst_entry __rcu *dst;
__be32 saddr;
};
struct metadata_dst;
struct ip_tunnel {
@@ -108,7 +115,7 @@ struct ip_tunnel {
int tun_hlen; /* Precalculated header length */
int mlink;
struct ip_tunnel_dst __percpu *dst_cache;
struct dst_cache dst_cache;
struct ip_tunnel_parm parms;
@@ -141,6 +148,7 @@ struct ip_tunnel {
#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)
#define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800)
#define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)
#define TUNNEL_NOCACHE __cpu_to_be16(0x2000)
#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT)
@@ -181,7 +189,7 @@ int ip_tunnel_encap_del_ops(const struct ip_tunnel_encap_ops *op,
static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
__be32 saddr, __be32 daddr,
u8 tos, u8 ttl,
u8 tos, u8 ttl, __be32 label,
__be16 tp_src, __be16 tp_dst,
__be64 tun_id, __be16 tun_flags)
{
@@ -192,6 +200,7 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
0, IP_TUNNEL_KEY_IPV4_PAD_LEN);
key->tos = tos;
key->ttl = ttl;
key->label = label;
key->tun_flags = tun_flags;
/* For the tunnel types on the top of IPsec, the tp_src and tp_dst of
@@ -207,6 +216,20 @@ static inline void ip_tunnel_key_init(struct ip_tunnel_key *key,
0, sizeof(*key) - IP_TUNNEL_KEY_SIZE);
}
static inline bool
ip_tunnel_dst_cache_usable(const struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
if (skb->mark)
return false;
if (!info)
return true;
if (info->key.tun_flags & TUNNEL_NOCACHE)
return false;
return true;
}
static inline unsigned short ip_tunnel_info_af(const struct ip_tunnel_info
*tun_info)
{
@@ -248,7 +271,6 @@ int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm *p);
void ip_tunnel_setup(struct net_device *dev, int net_id);
void ip_tunnel_dst_reset_all(struct ip_tunnel *t);
int ip_tunnel_encap_setup(struct ip_tunnel *t,
struct ip_tunnel_encap *ipencap);
@@ -273,15 +295,15 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
return INET_ECN_encapsulate(tos, inner);
}
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto,
bool xnet);
void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, u8 proto,
u8 tos, u8 ttl, __be16 df, bool xnet);
struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
gfp_t flags);
struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, bool gre_csum,
int gso_type_mask);
struct sk_buff *iptunnel_handle_offloads(struct sk_buff *skb, int gso_type_mask);
static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)
{
@@ -356,6 +378,17 @@ static inline void ip_tunnel_unneed_metadata(void)
{
}
static inline void ip_tunnel_info_opts_get(void *to,
const struct ip_tunnel_info *info)
{
}
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
const void *from, int len)
{
info->options_len = 0;
}
#endif /* CONFIG_INET */
#endif /* __NET_IP_TUNNELS_H */

View File

@@ -1588,6 +1588,23 @@ static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
}
#endif /* CONFIG_IP_VS_NFCT */
/* Really using conntrack? */
static inline bool ip_vs_conn_uses_conntrack(struct ip_vs_conn *cp,
struct sk_buff *skb)
{
#ifdef CONFIG_IP_VS_NFCT
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
if (!(cp->flags & IP_VS_CONN_F_NFCT))
return false;
ct = nf_ct_get(skb, &ctinfo);
if (ct && !nf_ct_is_untracked(ct))
return true;
#endif
return false;
}
static inline int
ip_vs_dest_conn_overhead(struct ip_vs_dest *dest)
{

View File

@@ -259,8 +259,12 @@ static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
rcu_read_lock();
opt = rcu_dereference(np->opt);
if (opt && !atomic_inc_not_zero(&opt->refcnt))
opt = NULL;
if (opt) {
if (!atomic_inc_not_zero(&opt->refcnt))
opt = NULL;
else
opt = rcu_pointer_handoff(opt);
}
rcu_read_unlock();
return opt;
}

226
include/net/kcm.h Normal file
View File

@@ -0,0 +1,226 @@
/*
* Kernel Connection Multiplexor
*
* Copyright (c) 2016 Tom Herbert <tom@herbertland.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*/
#ifndef __NET_KCM_H_
#define __NET_KCM_H_
#include <linux/skbuff.h>
#include <net/sock.h>
#include <uapi/linux/kcm.h>
extern unsigned int kcm_net_id;
#define KCM_STATS_ADD(stat, count) ((stat) += (count))
#define KCM_STATS_INCR(stat) ((stat)++)
struct kcm_psock_stats {
unsigned long long rx_msgs;
unsigned long long rx_bytes;
unsigned long long tx_msgs;
unsigned long long tx_bytes;
unsigned int rx_aborts;
unsigned int rx_mem_fail;
unsigned int rx_need_more_hdr;
unsigned int rx_msg_too_big;
unsigned int rx_msg_timeouts;
unsigned int rx_bad_hdr_len;
unsigned long long reserved;
unsigned long long unreserved;
unsigned int tx_aborts;
};
struct kcm_mux_stats {
unsigned long long rx_msgs;
unsigned long long rx_bytes;
unsigned long long tx_msgs;
unsigned long long tx_bytes;
unsigned int rx_ready_drops;
unsigned int tx_retries;
unsigned int psock_attach;
unsigned int psock_unattach_rsvd;
unsigned int psock_unattach;
};
struct kcm_stats {
unsigned long long rx_msgs;
unsigned long long rx_bytes;
unsigned long long tx_msgs;
unsigned long long tx_bytes;
};
struct kcm_tx_msg {
unsigned int sent;
unsigned int fragidx;
unsigned int frag_offset;
unsigned int msg_flags;
struct sk_buff *frag_skb;
struct sk_buff *last_skb;
};
struct kcm_rx_msg {
int full_len;
int accum_len;
int offset;
int early_eaten;
};
/* Socket structure for KCM client sockets */
struct kcm_sock {
struct sock sk;
struct kcm_mux *mux;
struct list_head kcm_sock_list;
int index;
u32 done : 1;
struct work_struct done_work;
struct kcm_stats stats;
/* Transmit */
struct kcm_psock *tx_psock;
struct work_struct tx_work;
struct list_head wait_psock_list;
struct sk_buff *seq_skb;
/* Don't use bit fields here, these are set under different locks */
bool tx_wait;
bool tx_wait_more;
/* Receive */
struct kcm_psock *rx_psock;
struct list_head wait_rx_list; /* KCMs waiting for receiving */
bool rx_wait;
u32 rx_disabled : 1;
};
struct bpf_prog;
/* Structure for an attached lower socket */
struct kcm_psock {
struct sock *sk;
struct kcm_mux *mux;
int index;
u32 tx_stopped : 1;
u32 rx_stopped : 1;
u32 done : 1;
u32 unattaching : 1;
void (*save_state_change)(struct sock *sk);
void (*save_data_ready)(struct sock *sk);
void (*save_write_space)(struct sock *sk);
struct list_head psock_list;
struct kcm_psock_stats stats;
/* Receive */
struct sk_buff *rx_skb_head;
struct sk_buff **rx_skb_nextp;
struct sk_buff *ready_rx_msg;
struct list_head psock_ready_list;
struct work_struct rx_work;
struct delayed_work rx_delayed_work;
struct bpf_prog *bpf_prog;
struct kcm_sock *rx_kcm;
unsigned long long saved_rx_bytes;
unsigned long long saved_rx_msgs;
struct timer_list rx_msg_timer;
unsigned int rx_need_bytes;
/* Transmit */
struct kcm_sock *tx_kcm;
struct list_head psock_avail_list;
unsigned long long saved_tx_bytes;
unsigned long long saved_tx_msgs;
};
/* Per net MUX list */
struct kcm_net {
struct mutex mutex;
struct kcm_psock_stats aggregate_psock_stats;
struct kcm_mux_stats aggregate_mux_stats;
struct list_head mux_list;
int count;
};
/* Structure for a MUX */
struct kcm_mux {
struct list_head kcm_mux_list;
struct rcu_head rcu;
struct kcm_net *knet;
struct list_head kcm_socks; /* All KCM sockets on MUX */
int kcm_socks_cnt; /* Total KCM socket count for MUX */
struct list_head psocks; /* List of all psocks on MUX */
int psocks_cnt; /* Total attached sockets */
struct kcm_mux_stats stats;
struct kcm_psock_stats aggregate_psock_stats;
/* Receive */
spinlock_t rx_lock ____cacheline_aligned_in_smp;
struct list_head kcm_rx_waiters; /* KCMs waiting for receiving */
struct list_head psocks_ready; /* List of psocks with a msg ready */
struct sk_buff_head rx_hold_queue;
/* Transmit */
spinlock_t lock ____cacheline_aligned_in_smp; /* TX and mux locking */
struct list_head psocks_avail; /* List of available psocks */
struct list_head kcm_tx_waiters; /* KCMs waiting for a TX psock */
};
#ifdef CONFIG_PROC_FS
int kcm_proc_init(void);
void kcm_proc_exit(void);
#else
static inline int kcm_proc_init(void) { return 0; }
static inline void kcm_proc_exit(void) { }
#endif
static inline void aggregate_psock_stats(struct kcm_psock_stats *stats,
struct kcm_psock_stats *agg_stats)
{
/* Save psock statistics in the mux when psock is being unattached. */
#define SAVE_PSOCK_STATS(_stat) (agg_stats->_stat += stats->_stat)
SAVE_PSOCK_STATS(rx_msgs);
SAVE_PSOCK_STATS(rx_bytes);
SAVE_PSOCK_STATS(rx_aborts);
SAVE_PSOCK_STATS(rx_mem_fail);
SAVE_PSOCK_STATS(rx_need_more_hdr);
SAVE_PSOCK_STATS(rx_msg_too_big);
SAVE_PSOCK_STATS(rx_msg_timeouts);
SAVE_PSOCK_STATS(rx_bad_hdr_len);
SAVE_PSOCK_STATS(tx_msgs);
SAVE_PSOCK_STATS(tx_bytes);
SAVE_PSOCK_STATS(reserved);
SAVE_PSOCK_STATS(unreserved);
SAVE_PSOCK_STATS(tx_aborts);
#undef SAVE_PSOCK_STATS
}
static inline void aggregate_mux_stats(struct kcm_mux_stats *stats,
struct kcm_mux_stats *agg_stats)
{
/* Save psock statistics in the mux when psock is being unattached. */
#define SAVE_MUX_STATS(_stat) (agg_stats->_stat += stats->_stat)
SAVE_MUX_STATS(rx_msgs);
SAVE_MUX_STATS(rx_bytes);
SAVE_MUX_STATS(tx_msgs);
SAVE_MUX_STATS(tx_bytes);
SAVE_MUX_STATS(rx_ready_drops);
SAVE_MUX_STATS(psock_attach);
SAVE_MUX_STATS(psock_unattach_rsvd);
SAVE_MUX_STATS(psock_unattach);
#undef SAVE_MUX_STATS
}
#endif /* __NET_KCM_H_ */

View File

@@ -39,7 +39,7 @@ struct l3mdev_ops {
#ifdef CONFIG_NET_L3_MASTER_DEV
int l3mdev_master_ifindex_rcu(struct net_device *dev);
int l3mdev_master_ifindex_rcu(const struct net_device *dev);
static inline int l3mdev_master_ifindex(struct net_device *dev)
{
int ifindex;
@@ -179,7 +179,7 @@ struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
#else
static inline int l3mdev_master_ifindex_rcu(struct net_device *dev)
static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
{
return 0;
}

View File

@@ -170,6 +170,8 @@ static inline int lwtunnel_input(struct sk_buff *skb)
return -EOPNOTSUPP;
}
#endif
#endif /* CONFIG_LWTUNNEL */
#define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
#endif /* __NET_LWTUNNEL_H */

View File

@@ -5,7 +5,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 Intel Deutschland GmbH
* Copyright (C) 2015 - 2016 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -298,6 +298,7 @@ struct ieee80211_vif_chanctx_switch {
* note that this is only called when it changes after the channel
* context had been assigned.
* @BSS_CHANGED_OCB: OCB join status changed
* @BSS_CHANGED_MU_GROUPS: VHT MU-MIMO group id or user position changed
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -323,6 +324,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_BEACON_INFO = 1<<20,
BSS_CHANGED_BANDWIDTH = 1<<21,
BSS_CHANGED_OCB = 1<<22,
BSS_CHANGED_MU_GROUPS = 1<<23,
/* when adding here, make sure to change ieee80211_reconfig */
};
@@ -435,6 +437,19 @@ struct ieee80211_event {
} u;
};
/**
* struct ieee80211_mu_group_data - STA's VHT MU-MIMO group data
*
* This structure describes the group id data of VHT MU-MIMO
*
* @membership: 64 bits array - a bit is set if station is member of the group
* @position: 2 bits per group id indicating the position in the group
*/
struct ieee80211_mu_group_data {
u8 membership[WLAN_MEMBERSHIP_LEN];
u8 position[WLAN_USER_POSITION_LEN];
};
/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
@@ -477,6 +492,7 @@ struct ieee80211_event {
* @enable_beacon: whether beaconing should be enabled or not
* @chandef: Channel definition for this BSS -- the hardware might be
* configured a higher bandwidth than this BSS uses, for example.
* @mu_group: VHT MU-MIMO group membership data
* @ht_operation_mode: HT operation mode like in &struct ieee80211_ht_operation.
* This field is only valid when the channel is a wide HT/VHT channel.
* Note that with TDLS this can be the case (channel is HT, protection must
@@ -535,6 +551,7 @@ struct ieee80211_bss_conf {
s32 cqm_rssi_thold;
u32 cqm_rssi_hyst;
struct cfg80211_chan_def chandef;
struct ieee80211_mu_group_data mu_group;
__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
int arp_addr_cnt;
bool qos;
@@ -691,12 +708,14 @@ enum mac80211_tx_info_flags {
* protocol frame (e.g. EAP)
* @IEEE80211_TX_CTRL_PS_RESPONSE: This frame is a response to a poll
* frame (PS-Poll or uAPSD).
* @IEEE80211_TX_CTRL_RATE_INJECT: This frame is injected with rate information
*
* These flags are used in tx_info->control.flags.
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0),
IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1),
IEEE80211_TX_CTRL_RATE_INJECT = BIT(2),
};
/*
@@ -993,6 +1012,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_MACTIME_END: The timestamp passed in the RX status (@mactime
* field) is valid and contains the time the last symbol of the MPDU
* (including FCS) was received.
* @RX_FLAG_MACTIME_PLCP_START: The timestamp passed in the RX status (@mactime
* field) is valid and contains the time the SYNC preamble was received.
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
* @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index
@@ -1014,6 +1035,14 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
* is stored in the @ampdu_delimiter_crc field)
* @RX_FLAG_LDPC: LDPC was used
* @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
* processing it in any regular way.
* This is useful if drivers offload some frames but still want to report
* them for sniffing purposes.
* @RX_FLAG_SKIP_MONITOR: Process and report frame to all interfaces except
* monitor interfaces.
* This is useful if drivers offload some frames but still want to report
* them for sniffing purposes.
* @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
* @RX_FLAG_10MHZ: 10 MHz (half channel) was used
* @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
@@ -1033,6 +1062,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0),
RX_FLAG_DECRYPTED = BIT(1),
RX_FLAG_MACTIME_PLCP_START = BIT(2),
RX_FLAG_MMIC_STRIPPED = BIT(3),
RX_FLAG_IV_STRIPPED = BIT(4),
RX_FLAG_FAILED_FCS_CRC = BIT(5),
@@ -1046,7 +1076,7 @@ enum mac80211_rx_flags {
RX_FLAG_HT_GF = BIT(13),
RX_FLAG_AMPDU_DETAILS = BIT(14),
RX_FLAG_PN_VALIDATED = BIT(15),
/* bit 16 free */
RX_FLAG_DUP_VALIDATED = BIT(16),
RX_FLAG_AMPDU_LAST_KNOWN = BIT(17),
RX_FLAG_AMPDU_IS_LAST = BIT(18),
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
@@ -1054,6 +1084,8 @@ enum mac80211_rx_flags {
RX_FLAG_MACTIME_END = BIT(21),
RX_FLAG_VHT = BIT(22),
RX_FLAG_LDPC = BIT(23),
RX_FLAG_ONLY_MONITOR = BIT(24),
RX_FLAG_SKIP_MONITOR = BIT(25),
RX_FLAG_STBC_MASK = BIT(26) | BIT(27),
RX_FLAG_10MHZ = BIT(28),
RX_FLAG_5MHZ = BIT(29),
@@ -1072,6 +1104,7 @@ enum mac80211_rx_flags {
* @RX_VHT_FLAG_160MHZ: 160 MHz was used
* @RX_VHT_FLAG_BF: packet was beamformed
*/
enum mac80211_rx_vht_flags {
RX_VHT_FLAG_80MHZ = BIT(0),
RX_VHT_FLAG_160MHZ = BIT(1),
@@ -1091,6 +1124,8 @@ enum mac80211_rx_vht_flags {
* it but can store it and pass it back to the driver for synchronisation
* @band: the active band when this frame was received
* @freq: frequency the radio was tuned to when receiving this frame, in MHz
* This field must be set for management frames, but isn't strictly needed
* for data (other) frames - for those it only affects radiotap reporting.
* @signal: signal strength when receiving this frame, either in dBm, in dB or
* unspecified depending on the hardware capabilities flags
* @IEEE80211_HW_SIGNAL_*
@@ -1347,6 +1382,7 @@ enum ieee80211_vif_flags {
* @csa_active: marks whether a channel switch is going on. Internally it is
* write-protected by sdata_lock and local->mtx so holding either is fine
* for read access.
* @mu_mimo_owner: indicates interface owns MU-MIMO capability
* @driver_flags: flags/capabilities the driver has for this interface,
* these need to be set (or cleared) when the interface is added
* or, if supported by the driver, the interface type is changed
@@ -1373,6 +1409,7 @@ struct ieee80211_vif {
u8 addr[ETH_ALEN];
bool p2p;
bool csa_active;
bool mu_mimo_owner;
u8 cab_queue;
u8 hw_queue[IEEE80211_NUM_ACS];
@@ -1486,9 +1523,8 @@ enum ieee80211_key_flags {
* wants to be given when a frame is transmitted and needs to be
* encrypted in hardware.
* @cipher: The key's cipher suite selector.
* @tx_pn: PN used for TX on non-TKIP keys, may be used by the driver
* as well if it needs to do software PN assignment by itself
* (e.g. due to TSO)
* @tx_pn: PN used for TX keys, may be used by the driver as well if it
* needs to do software PN assignment by itself (e.g. due to TSO)
* @flags: key flags, see &enum ieee80211_key_flags.
* @keyidx: the key index (0-3)
* @keylen: key material length
@@ -1514,6 +1550,9 @@ struct ieee80211_key_conf {
#define IEEE80211_MAX_PN_LEN 16
#define TKIP_PN_TO_IV16(pn) ((u16)(pn & 0xffff))
#define TKIP_PN_TO_IV32(pn) ((u32)((pn >> 16) & 0xffffffff))
/**
* struct ieee80211_key_seq - key sequence counter
*
@@ -1684,6 +1723,18 @@ struct ieee80211_sta_rates {
* @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only
* valid if the STA is a TDLS peer in the first place.
* @mfp: indicates whether the STA uses management frame protection or not.
* @max_amsdu_subframes: indicates the maximal number of MSDUs in a single
* A-MSDU. Taken from the Extended Capabilities element. 0 means
* unlimited.
* @max_amsdu_len: indicates the maximal length of an A-MSDU in bytes. This
* field is always valid for packets with a VHT preamble. For packets
* with a HT preamble, additional limits apply:
* + If the skb is transmitted as part of a BA agreement, the
* A-MSDU maximal size is min(max_amsdu_len, 4065) bytes.
* + If the skb is not part of a BA aggreement, the A-MSDU maximal
* size is min(max_amsdu_len, 7935) bytes.
* Both additional HT limits must be enforced by the low level driver.
* This is defined by the spec (IEEE 802.11-2012 section 8.3.2.2 NOTE 2).
* @txq: per-TID data TX queues (if driver uses the TXQ abstraction)
*/
struct ieee80211_sta {
@@ -1702,6 +1753,8 @@ struct ieee80211_sta {
bool tdls;
bool tdls_initiator;
bool mfp;
u8 max_amsdu_subframes;
u16 max_amsdu_len;
struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
@@ -1910,6 +1963,11 @@ struct ieee80211_txq {
* by just its MAC address; this prevents, for example, the same station
* from connecting to two virtual AP interfaces at the same time.
*
* @IEEE80211_HW_SUPPORTS_REORDERING_BUFFER: Hardware (or driver) manages the
* reordering buffer internally, guaranteeing mac80211 receives frames in
* order and does not need to manage its own reorder buffer or BA session
* timeout.
*
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -1946,6 +2004,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
IEEE80211_HW_BEACON_TX_STATUS,
IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -2167,7 +2226,7 @@ static inline void SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev
* @hw: the &struct ieee80211_hw to set the MAC address for
* @addr: the address to set
*/
static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr)
static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, const u8 *addr)
{
memcpy(hw->wiphy->perm_addr, addr, ETH_ALEN);
}
@@ -2683,6 +2742,33 @@ enum ieee80211_ampdu_mlme_action {
IEEE80211_AMPDU_TX_OPERATIONAL,
};
/**
* struct ieee80211_ampdu_params - AMPDU action parameters
*
* @action: the ampdu action, value from %ieee80211_ampdu_mlme_action.
* @sta: peer of this AMPDU session
* @tid: tid of the BA session
* @ssn: start sequence number of the session. TX/RX_STOP can pass 0. When
* action is set to %IEEE80211_AMPDU_RX_START the driver passes back the
* actual ssn value used to start the session and writes the value here.
* @buf_size: reorder buffer size (number of subframes). Valid only when the
* action is set to %IEEE80211_AMPDU_RX_START or
* %IEEE80211_AMPDU_TX_OPERATIONAL
* @amsdu: indicates the peer's ability to receive A-MSDU within A-MPDU.
* valid when the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL
* @timeout: BA session timeout. Valid only when the action is set to
* %IEEE80211_AMPDU_RX_START
*/
struct ieee80211_ampdu_params {
enum ieee80211_ampdu_mlme_action action;
struct ieee80211_sta *sta;
u16 tid;
u16 ssn;
u8 buf_size;
bool amsdu;
u16 timeout;
};
/**
* enum ieee80211_frame_release_type - frame release reason
* @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
@@ -3027,13 +3113,9 @@ enum ieee80211_reconfig_type {
* @ampdu_action: Perform a certain A-MPDU action
* The RA/TID combination determines the destination and TID we want
* the ampdu action to be performed for. The action is defined through
* ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
* is the first frame we expect to perform the action on. Notice
* that TX/RX_STOP can pass NULL for this parameter.
* The @buf_size parameter is only valid when the action is set to
* %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
* buffer size (number of subframes) for this session -- the driver
* may neither send aggregates containing more subframes than this
* ieee80211_ampdu_mlme_action.
* When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
* may neither send aggregates containing more subframes than @buf_size
* nor send aggregates in a way that lost frames would exceed the
* buffer size. If just limiting the aggregate size, this would be
* possible with a buf_size of 8:
@@ -3044,9 +3126,6 @@ enum ieee80211_reconfig_type {
* buffer size of 8. Correct ways to retransmit #1 would be:
* - TX: 1 or 18 or 81
* Even "189" would be wrong since 1 could be lost again.
* The @amsdu parameter is valid when the action is set to
* %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's ability
* to receive A-MSDU within A-MPDU.
*
* Returns a negative error code on failure.
* The callback can sleep.
@@ -3388,9 +3467,7 @@ struct ieee80211_ops {
int (*tx_last_beacon)(struct ieee80211_hw *hw);
int (*ampdu_action)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
u8 buf_size, bool amsdu);
struct ieee80211_ampdu_params *params);
int (*get_survey)(struct ieee80211_hw *hw, int idx,
struct survey_info *survey);
void (*rfkill_poll)(struct ieee80211_hw *hw);
@@ -4374,21 +4451,19 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
struct sk_buff *skb, u8 *p2k);
/**
* ieee80211_get_key_tx_seq - get key TX sequence counter
* ieee80211_tkip_add_iv - write TKIP IV and Ext. IV to pos
*
* @pos: start of crypto header
* @keyconf: the parameter passed with the set key
* @seq: buffer to receive the sequence data
* @pn: PN to add
*
* This function allows a driver to retrieve the current TX IV/PN
* for the given key. It must not be called if IV generation is
* offloaded to the device.
* Returns: pointer to the octet following IVs (i.e. beginning of
* the packet payload)
*
* Note that this function may only be called when no TX processing
* can be done concurrently, for example when queues are stopped
* and the stop has been synchronized.
* This function writes the tkip IV value to pos (which should
* point to the crypto header)
*/
void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
struct ieee80211_key_seq *seq);
u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key_conf *keyconf, u64 pn);
/**
* ieee80211_get_key_rx_seq - get key RX sequence counter
@@ -4409,23 +4484,6 @@ void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
int tid, struct ieee80211_key_seq *seq);
/**
* ieee80211_set_key_tx_seq - set key TX sequence counter
*
* @keyconf: the parameter passed with the set key
* @seq: new sequence data
*
* This function allows a driver to set the current TX IV/PNs for the
* given key. This is useful when resuming from WoWLAN sleep and the
* device may have transmitted frames using the PTK, e.g. replies to
* ARP requests.
*
* Note that this function may only be called when no TX processing
* can be done concurrently.
*/
void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf,
struct ieee80211_key_seq *seq);
/**
* ieee80211_set_key_rx_seq - set key RX sequence counter
*
@@ -5120,6 +5178,24 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw);
void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
const u8 *addr);
/**
* ieee80211_mark_rx_ba_filtered_frames - move RX BA window and mark filtered
* @pubsta: station struct
* @tid: the session's TID
* @ssn: starting sequence number of the bitmap, all frames before this are
* assumed to be out of the window after the call
* @filtered: bitmap of filtered frames, BIT(0) is the @ssn entry etc.
* @received_mpdus: number of received mpdus in firmware
*
* This function moves the BA window and releases all frames before @ssn, and
* marks frames marked in the bitmap as having been filtered. Afterwards, it
* checks if any frames in the window starting from @ssn can now be released
* (in case they were only waiting for frames that were filtered.)
*/
void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid,
u16 ssn, u64 filtered,
u16 received_mpdus);
/**
* ieee80211_send_bar - send a BlockAckReq frame
*
@@ -5371,6 +5447,21 @@ ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
return ieee80211_iftype_p2p(vif->type, vif->p2p);
}
/**
* ieee80211_update_mu_groups - set the VHT MU-MIMO groud data
*
* @vif: the specified virtual interface
* @membership: 64 bits array - a bit is set if station is member of the group
* @position: 2 bits per group id indicating the position in the group
*
* Note: This function assumes that the given vif is valid and the position and
* membership data is of the correct size and are in the same byte order as the
* matching GroupId management frame.
* Calls to this function need to be serialized with RX path.
*/
void ieee80211_update_mu_groups(struct ieee80211_vif *vif,
const u8 *membership, const u8 *position);
void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
int rssi_min_thold,
int rssi_max_thold);
@@ -5523,4 +5614,19 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
*/
struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
struct ieee80211_txq *txq);
/**
* ieee80211_txq_get_depth - get pending frame/byte count of given txq
*
* The values are not guaranteed to be coherent with regard to each other, i.e.
* txq state can change half-way of this function and the caller may end up
* with "new" frame_cnt and "old" byte_cnt or vice-versa.
*
* @txq: pointer obtained from station or virtual interface
* @frame_cnt: pointer to store frame count
* @byte_cnt: pointer to store byte count
*/
void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
unsigned long *frame_cnt,
unsigned long *byte_cnt);
#endif /* MAC80211_H */

View File

@@ -16,10 +16,10 @@
#ifndef NET_MAC802154_H
#define NET_MAC802154_H
#include <asm/unaligned.h>
#include <net/af_ieee802154.h>
#include <linux/ieee802154.h>
#include <linux/skbuff.h>
#include <linux/unaligned/memmove.h>
#include <net/cfg802154.h>
@@ -247,13 +247,14 @@ struct ieee802154_ops {
*/
static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
{
/* return some invalid fc on failure */
if (unlikely(skb->len < 2)) {
/* check if we can fc at skb_mac_header of sk buffer */
if (unlikely(!skb_mac_header_was_set(skb) ||
(skb_tail_pointer(skb) - skb_mac_header(skb)) < 2)) {
WARN_ON(1);
return cpu_to_le16(0);
}
return (__force __le16)__get_unaligned_memmove16(skb_mac_header(skb));
return get_unaligned_le16(skb_mac_header(skb));
}
/**
@@ -263,7 +264,7 @@ static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
*/
static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src)
{
__put_unaligned_memmove64(swab64p(be64_src), le64_dst);
put_unaligned_le64(get_unaligned_be64(be64_src), le64_dst);
}
/**
@@ -273,7 +274,7 @@ static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src)
*/
static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
{
__put_unaligned_memmove64(swab64p(le64_src), be64_dst);
put_unaligned_be64(get_unaligned_le64(le64_src), be64_dst);
}
/**
@@ -283,7 +284,7 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
*/
static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src)
{
__put_unaligned_memmove16(swab16p(le16_src), be16_dst);
put_unaligned_be16(get_unaligned_le16(le16_src), be16_dst);
}
/**

View File

@@ -2,7 +2,9 @@
#define _NFT_MASQ_H_
struct nft_masq {
u32 flags;
u32 flags;
enum nft_registers sreg_proto_min:8;
enum nft_registers sreg_proto_max:8;
};
extern const struct nla_policy nft_masq_policy[];

View File

@@ -80,9 +80,13 @@ struct netns_ipv4 {
int sysctl_tcp_ecn;
int sysctl_tcp_ecn_fallback;
int sysctl_ip_default_ttl;
int sysctl_ip_no_pmtu_disc;
int sysctl_ip_fwd_use_pmtu;
int sysctl_ip_nonlocal_bind;
/* Shall we try to damage output packets if routing dev changes? */
int sysctl_ip_dynaddr;
int sysctl_ip_early_demux;
int sysctl_fwmark_reflect;
int sysctl_tcp_fwmark_accept;
@@ -98,6 +102,21 @@ struct netns_ipv4 {
int sysctl_tcp_keepalive_probes;
int sysctl_tcp_keepalive_intvl;
int sysctl_tcp_syn_retries;
int sysctl_tcp_synack_retries;
int sysctl_tcp_syncookies;
int sysctl_tcp_reordering;
int sysctl_tcp_retries1;
int sysctl_tcp_retries2;
int sysctl_tcp_orphan_retries;
int sysctl_tcp_fin_timeout;
unsigned int sysctl_tcp_notsent_lowat;
int sysctl_igmp_max_memberships;
int sysctl_igmp_max_msf;
int sysctl_igmp_llm_reports;
int sysctl_igmp_qrv;
struct ping_group_range ping_group_range;
atomic_t dev_addr_genid;

View File

@@ -58,7 +58,10 @@ struct netns_ipv6 {
struct timer_list ip6_fib_timer;
struct hlist_head *fib_table_hash;
struct fib6_table *fib6_main_tbl;
struct list_head fib6_walkers;
struct dst_ops ip6_dst_ops;
rwlock_t fib6_walker_lock;
spinlock_t fib6_gc_lock;
unsigned int ip6_rt_gc_expire;
unsigned long ip6_rt_last_gc;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES

View File

@@ -51,7 +51,7 @@ void pn_sock_init(void);
struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa);
void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb);
void phonet_get_local_port_range(int *min, int *max);
void pn_sock_hash(struct sock *sk);
int pn_sock_hash(struct sock *sk);
void pn_sock_unhash(struct sock *sk);
int pn_sock_get_port(struct sock *sk, unsigned short sport);

View File

@@ -65,7 +65,7 @@ struct pingfakehdr {
};
int ping_get_port(struct sock *sk, unsigned short ident);
void ping_hash(struct sock *sk);
int ping_hash(struct sock *sk);
void ping_unhash(struct sock *sk);
int ping_init_sock(struct sock *sk);

View File

@@ -358,4 +358,69 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
}
#endif /* CONFIG_NET_CLS_IND */
struct tc_cls_u32_knode {
struct tcf_exts *exts;
struct tc_u32_sel *sel;
u32 handle;
u32 val;
u32 mask;
u32 link_handle;
u8 fshift;
};
struct tc_cls_u32_hnode {
u32 handle;
u32 prio;
unsigned int divisor;
};
enum tc_clsu32_command {
TC_CLSU32_NEW_KNODE,
TC_CLSU32_REPLACE_KNODE,
TC_CLSU32_DELETE_KNODE,
TC_CLSU32_NEW_HNODE,
TC_CLSU32_REPLACE_HNODE,
TC_CLSU32_DELETE_HNODE,
};
struct tc_cls_u32_offload {
/* knode values */
enum tc_clsu32_command command;
union {
struct tc_cls_u32_knode knode;
struct tc_cls_u32_hnode hnode;
};
};
/* tca flags definitions */
#define TCA_CLS_FLAGS_SKIP_HW 1
static inline bool tc_should_offload(struct net_device *dev, u32 flags)
{
if (!(dev->features & NETIF_F_HW_TC))
return false;
if (flags & TCA_CLS_FLAGS_SKIP_HW)
return false;
if (!dev->netdev_ops->ndo_setup_tc)
return false;
return true;
}
enum tc_fl_command {
TC_CLSFLOWER_REPLACE,
TC_CLSFLOWER_DESTROY,
};
struct tc_cls_flower_offload {
enum tc_fl_command command;
unsigned long cookie;
struct flow_dissector *dissector;
struct fl_flow_key *mask;
struct fl_flow_key *key;
struct tcf_exts *exts;
};
#endif

View File

@@ -57,7 +57,7 @@ int raw_seq_open(struct inode *ino, struct file *file,
#endif
void raw_hash_sk(struct sock *sk);
int raw_hash_sk(struct sock *sk);
void raw_unhash_sk(struct sock *sk);
struct raw_sock {

View File

@@ -329,14 +329,13 @@ static inline int inet_iif(const struct sk_buff *skb)
return skb->skb_iif;
}
extern int sysctl_ip_default_ttl;
static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
{
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
struct net *net = dev_net(dst->dev);
if (hoplimit == 0)
hoplimit = sysctl_ip_default_ttl;
hoplimit = net->ipv4.sysctl_ip_default_ttl;
return hoplimit;
}

View File

@@ -345,6 +345,12 @@ extern struct Qdisc_ops pfifo_fast_ops;
extern struct Qdisc_ops mq_qdisc_ops;
extern struct Qdisc_ops noqueue_qdisc_ops;
extern const struct Qdisc_ops *default_qdisc_ops;
static inline const struct Qdisc_ops *
get_default_qdisc_ops(const struct net_device *dev, int ntx)
{
return ntx < dev->real_num_tx_queues ?
default_qdisc_ops : &pfifo_fast_ops;
}
struct Qdisc_class_common {
u32 classid;
@@ -396,7 +402,8 @@ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
struct Qdisc *qdisc);
void qdisc_reset(struct Qdisc *qdisc);
void qdisc_destroy(struct Qdisc *qdisc);
void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n,
unsigned int len);
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops);
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
@@ -707,6 +714,23 @@ static inline void qdisc_reset_queue(struct Qdisc *sch)
sch->qstats.backlog = 0;
}
static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
struct Qdisc **pold)
{
struct Qdisc *old;
sch_tree_lock(sch);
old = *pold;
*pold = new;
if (old != NULL) {
qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog);
qdisc_reset(old);
}
sch_tree_unlock(sch);
return old;
}
static inline unsigned int __qdisc_queue_drop(struct Qdisc *sch,
struct sk_buff_head *list)
{

View File

@@ -31,12 +31,12 @@
#define __sctp_auth_h__
#include <linux/list.h>
#include <linux/crypto.h>
struct sctp_endpoint;
struct sctp_association;
struct sctp_authkey;
struct sctp_hmacalgo;
struct crypto_shash;
/*
* Define a generic struct that will hold all the info
@@ -90,7 +90,7 @@ int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
struct sctp_association *asoc,
gfp_t gfp);
int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp);
void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]);
void sctp_auth_destroy_hmacs(struct crypto_shash *auth_hmacs[]);
struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id);
struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,

View File

@@ -201,7 +201,7 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
const struct sctp_sndrcvinfo *sinfo,
int len, const __u8 flags,
__u16 ssn);
__u16 ssn, gfp_t gfp);
struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
const __u32);
struct sctp_chunk *sctp_make_sack(const struct sctp_association *);

View File

@@ -82,7 +82,7 @@ struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_ep_common;
struct sctp_ssnmap;
struct crypto_hash;
struct crypto_shash;
#include <net/sctp/tsnmap.h>
@@ -166,7 +166,7 @@ struct sctp_sock {
struct sctp_pf *pf;
/* Access to HMAC transform. */
struct crypto_hash *hmac;
struct crypto_shash *hmac;
char *sctp_hmac_alg;
/* What is our base endpointer? */
@@ -535,7 +535,6 @@ struct sctp_datamsg {
struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
struct sctp_sndrcvinfo *,
struct iov_iter *);
void sctp_datamsg_free(struct sctp_datamsg *);
void sctp_datamsg_put(struct sctp_datamsg *);
void sctp_chunk_fail(struct sctp_chunk *, int error);
int sctp_chunk_abandoned(struct sctp_chunk *);
@@ -656,7 +655,7 @@ void sctp_chunk_free(struct sctp_chunk *);
void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
struct sctp_chunk *sctp_chunkify(struct sk_buff *,
const struct sctp_association *,
struct sock *);
struct sock *, gfp_t gfp);
void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
union sctp_addr *);
const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
@@ -718,10 +717,10 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *,
__u16 sport, __u16 dport);
struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
struct sctp_chunk *, int);
struct sctp_chunk *, int, gfp_t);
sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
struct sctp_chunk *);
int sctp_packet_transmit(struct sctp_packet *);
int sctp_packet_transmit(struct sctp_packet *, gfp_t);
void sctp_packet_free(struct sctp_packet *);
static inline int sctp_packet_empty(struct sctp_packet *packet)
@@ -1054,7 +1053,7 @@ struct sctp_outq {
void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
void sctp_outq_teardown(struct sctp_outq *);
void sctp_outq_free(struct sctp_outq*);
int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk, gfp_t);
int sctp_outq_sack(struct sctp_outq *, struct sctp_chunk *);
int sctp_outq_is_empty(const struct sctp_outq *);
void sctp_outq_restart(struct sctp_outq *);
@@ -1062,7 +1061,7 @@ void sctp_outq_restart(struct sctp_outq *);
void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
sctp_retransmit_reason_t);
void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
int sctp_outq_uncork(struct sctp_outq *);
int sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
/* Uncork and flush an outqueue. */
static inline void sctp_outq_cork(struct sctp_outq *q)
{
@@ -1234,7 +1233,7 @@ struct sctp_endpoint {
/* SCTP AUTH: array of the HMACs that will be allocated
* we need this per association so that we don't serialize
*/
struct crypto_hash **auth_hmacs;
struct crypto_shash **auth_hmacs;
/* SCTP-AUTH: hmacs for the endpoint encoded into parameter */
struct sctp_hmac_algo_param *auth_hmacs_list;

View File

@@ -984,7 +984,7 @@ struct proto {
void (*release_cb)(struct sock *sk);
/* Keeping track of sk's, looking them up, and port selection methods. */
void (*hash)(struct sock *sk);
int (*hash)(struct sock *sk);
void (*unhash)(struct sock *sk);
void (*rehash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
@@ -1194,10 +1194,10 @@ static inline void sock_prot_inuse_add(struct net *net, struct proto *prot,
/* With per-bucket locks this operation is not-atomic, so that
* this version is not worse.
*/
static inline void __sk_prot_rehash(struct sock *sk)
static inline int __sk_prot_rehash(struct sock *sk)
{
sk->sk_prot->unhash(sk);
sk->sk_prot->hash(sk);
return sk->sk_prot->hash(sk);
}
void sk_prot_clear_portaddr_nulls(struct sock *sk, int size);

View File

@@ -2,6 +2,7 @@
#define __NET_TC_GACT_H
#include <net/act_api.h>
#include <linux/tc_act/tc_gact.h>
struct tcf_gact {
struct tcf_common common;
@@ -15,4 +16,19 @@ struct tcf_gact {
#define to_gact(a) \
container_of(a->priv, struct tcf_gact, common)
static inline bool is_tcf_gact_shot(const struct tc_action *a)
{
#ifdef CONFIG_NET_CLS_ACT
struct tcf_gact *gact;
if (a->ops && a->ops->type != TCA_ACT_GACT)
return false;
gact = a->priv;
if (gact->tcf_action == TC_ACT_SHOT)
return true;
#endif
return false;
}
#endif /* __NET_TC_GACT_H */

View File

@@ -0,0 +1,61 @@
#ifndef __NET_TC_IFE_H
#define __NET_TC_IFE_H
#include <net/act_api.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/module.h>
#define IFE_METAHDRLEN 2
struct tcf_ife_info {
struct tcf_common common;
u8 eth_dst[ETH_ALEN];
u8 eth_src[ETH_ALEN];
u16 eth_type;
u16 flags;
/* list of metaids allowed */
struct list_head metalist;
};
#define to_ife(a) \
container_of(a->priv, struct tcf_ife_info, common)
struct tcf_meta_info {
const struct tcf_meta_ops *ops;
void *metaval;
u16 metaid;
struct list_head metalist;
};
struct tcf_meta_ops {
u16 metaid; /*Maintainer provided ID */
u16 metatype; /*netlink attribute type (look at net/netlink.h) */
const char *name;
const char *synopsis;
struct list_head list;
int (*check_presence)(struct sk_buff *, struct tcf_meta_info *);
int (*encode)(struct sk_buff *, void *, struct tcf_meta_info *);
int (*decode)(struct sk_buff *, void *, u16 len);
int (*get)(struct sk_buff *skb, struct tcf_meta_info *mi);
int (*alloc)(struct tcf_meta_info *, void *);
void (*release)(struct tcf_meta_info *);
int (*validate)(void *val, int len);
struct module *owner;
};
#define MODULE_ALIAS_IFE_META(metan) MODULE_ALIAS("ifemeta" __stringify_1(metan))
int ife_get_meta_u32(struct sk_buff *skb, struct tcf_meta_info *mi);
int ife_get_meta_u16(struct sk_buff *skb, struct tcf_meta_info *mi);
int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
const void *dval);
int ife_alloc_meta_u32(struct tcf_meta_info *mi, void *metaval);
int ife_alloc_meta_u16(struct tcf_meta_info *mi, void *metaval);
int ife_check_meta_u32(u32 metaval, struct tcf_meta_info *mi);
int ife_encode_meta_u32(u32 metaval, void *skbdata, struct tcf_meta_info *mi);
int ife_validate_meta_u32(void *val, int len);
int ife_validate_meta_u16(void *val, int len);
void ife_release_meta_gen(struct tcf_meta_info *mi);
int register_ife_op(struct tcf_meta_ops *mops);
int unregister_ife_op(struct tcf_meta_ops *mops);
#endif /* __NET_TC_IFE_H */

View File

@@ -20,6 +20,7 @@
#define __NET_TC_SKBEDIT_H
#include <net/act_api.h>
#include <linux/tc_act/tc_skbedit.h>
struct tcf_skbedit {
struct tcf_common common;
@@ -32,4 +33,19 @@ struct tcf_skbedit {
#define to_skbedit(a) \
container_of(a->priv, struct tcf_skbedit, common)
/* Return true iff action is mark */
static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
{
#ifdef CONFIG_NET_CLS_ACT
if (a->ops && a->ops->type == TCA_ACT_SKBEDIT)
return to_skbedit(a)->flags == SKBEDIT_F_MARK;
#endif
return false;
}
static inline u32 tcf_skbedit_mark(const struct tc_action *a)
{
return to_skbedit(a)->mark;
}
#endif /* __NET_TC_SKBEDIT_H */

View File

@@ -27,7 +27,6 @@
#include <linux/cache.h>
#include <linux/percpu.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
#include <linux/cryptohash.h>
#include <linux/kref.h>
#include <linux/ktime.h>
@@ -239,13 +238,6 @@ extern struct inet_timewait_death_row tcp_death_row;
extern int sysctl_tcp_timestamps;
extern int sysctl_tcp_window_scaling;
extern int sysctl_tcp_sack;
extern int sysctl_tcp_fin_timeout;
extern int sysctl_tcp_syn_retries;
extern int sysctl_tcp_synack_retries;
extern int sysctl_tcp_retries1;
extern int sysctl_tcp_retries2;
extern int sysctl_tcp_orphan_retries;
extern int sysctl_tcp_syncookies;
extern int sysctl_tcp_fastopen;
extern int sysctl_tcp_retrans_collapse;
extern int sysctl_tcp_stdurg;
@@ -274,7 +266,6 @@ extern int sysctl_tcp_thin_dupack;
extern int sysctl_tcp_early_retrans;
extern int sysctl_tcp_limit_output_bytes;
extern int sysctl_tcp_challenge_ack_limit;
extern unsigned int sysctl_tcp_notsent_lowat;
extern int sysctl_tcp_min_tso_segs;
extern int sysctl_tcp_min_rtt_wlen;
extern int sysctl_tcp_autocorking;
@@ -568,6 +559,7 @@ void tcp_rearm_rto(struct sock *sk);
void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req);
void tcp_reset(struct sock *sk);
void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb);
void tcp_fin(struct sock *sk);
/* tcp_timer.c */
void tcp_init_xmit_timers(struct sock *);
@@ -963,9 +955,11 @@ static inline void tcp_enable_fack(struct tcp_sock *tp)
*/
static inline void tcp_enable_early_retrans(struct tcp_sock *tp)
{
struct net *net = sock_net((struct sock *)tp);
tp->do_early_retrans = sysctl_tcp_early_retrans &&
sysctl_tcp_early_retrans < 4 && !sysctl_tcp_thin_dupack &&
sysctl_tcp_reordering == 3;
net->ipv4.sysctl_tcp_reordering == 3;
}
static inline void tcp_disable_early_retrans(struct tcp_sock *tp)
@@ -1252,7 +1246,7 @@ static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)
static inline int tcp_fin_time(const struct sock *sk)
{
int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout;
int fin_timeout = tcp_sk(sk)->linger2 ? : sock_net(sk)->ipv4.sysctl_tcp_fin_timeout;
const int rto = inet_csk(sk)->icsk_rto;
if (fin_timeout < (rto << 2) - (rto >> 1))
@@ -1325,9 +1319,6 @@ static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
tp->retransmit_skb_hint = NULL;
}
/* MD5 Signature */
struct crypto_hash;
union tcp_md5_addr {
struct in_addr a4;
#if IS_ENABLED(CONFIG_IPV6)
@@ -1376,7 +1367,7 @@ union tcp_md5sum_block {
/* - pool: digest algorithm, hash description and scratch buffer */
struct tcp_md5sig_pool {
struct hash_desc md5_desc;
struct ahash_request *md5_req;
union tcp_md5sum_block md5_blk;
};
@@ -1437,6 +1428,7 @@ void tcp_free_fastopen_req(struct tcp_sock *tp);
extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
int tcp_fastopen_reset_cipher(void *key, unsigned int len);
void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
struct tcp_fastopen_cookie *foc,
@@ -1685,7 +1677,8 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr);
static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp)
{
return tp->notsent_lowat ?: sysctl_tcp_notsent_lowat;
struct net *net = sock_net((struct sock *)tp);
return tp->notsent_lowat ?: net->ipv4.sysctl_tcp_notsent_lowat;
}
static inline bool tcp_stream_memory_free(const struct sock *sk)
@@ -1819,4 +1812,38 @@ static inline void skb_set_tcp_pure_ack(struct sk_buff *skb)
skb->truesize = 2;
}
static inline int tcp_inq(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
int answ;
if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
answ = 0;
} else if (sock_flag(sk, SOCK_URGINLINE) ||
!tp->urg_data ||
before(tp->urg_seq, tp->copied_seq) ||
!before(tp->urg_seq, tp->rcv_nxt)) {
answ = tp->rcv_nxt - tp->copied_seq;
/* Subtract 1, if FIN was received */
if (answ && sock_flag(sk, SOCK_DONE))
answ--;
} else {
answ = tp->urg_seq - tp->copied_seq;
}
return answ;
}
static inline void tcp_segs_in(struct tcp_sock *tp, const struct sk_buff *skb)
{
u16 segs_in;
segs_in = max_t(u16, 1, skb_shinfo(skb)->gso_segs);
tp->segs_in += segs_in;
if (skb->len > tcp_hdrlen(skb))
tp->data_segs_in += segs_in;
}
#endif /* _TCP_H */

View File

@@ -177,9 +177,10 @@ static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)
}
/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */
static inline void udp_lib_hash(struct sock *sk)
static inline int udp_lib_hash(struct sock *sk)
{
BUG();
return 0;
}
void udp_lib_unhash(struct sock *sk);

View File

@@ -88,8 +88,8 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb,
struct net_device *dev, struct in6_addr *saddr,
struct in6_addr *daddr,
__u8 prio, __u8 ttl, __be16 src_port,
__be16 dst_port, bool nocheck);
__u8 prio, __u8 ttl, __be32 label,
__be16 src_port, __be16 dst_port, bool nocheck);
#endif
void udp_tunnel_sock_release(struct socket *sock);
@@ -103,7 +103,7 @@ static inline struct sk_buff *udp_tunnel_handle_offloads(struct sk_buff *skb,
{
int type = udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
return iptunnel_handle_offloads(skb, udp_csum, type);
return iptunnel_handle_offloads(skb, type);
}
static inline void udp_tunnel_gro_complete(struct sk_buff *skb, int nhoff)

View File

@@ -9,17 +9,71 @@
#include <linux/udp.h>
#include <net/dst_metadata.h>
#define VNI_HASH_BITS 10
#define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
/*
* VXLAN Group Based Policy Extension:
/* VXLAN protocol (RFC 7348) header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |1|-|-|-|1|-|-|-|R|D|R|R|A|R|R|R| Group Policy ID |
* |R|R|R|R|I|R|R|R| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* I = VXLAN Network Identifier (VNI) present.
*/
struct vxlanhdr {
__be32 vx_flags;
__be32 vx_vni;
};
/* VXLAN header flags. */
#define VXLAN_HF_VNI cpu_to_be32(BIT(27))
#define VXLAN_N_VID (1u << 24)
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
#define VXLAN_VNI_MASK cpu_to_be32(VXLAN_VID_MASK << 8)
#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
#define VNI_HASH_BITS 10
#define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
#define FDB_HASH_BITS 8
#define FDB_HASH_SIZE (1<<FDB_HASH_BITS)
/* Remote checksum offload for VXLAN (VXLAN_F_REMCSUM_[RT]X):
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |R|R|R|R|I|R|R|R|R|R|C| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) |O| Csum start |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* C = Remote checksum offload bit. When set indicates that the
* remote checksum offload data is present.
*
* O = Offset bit. Indicates the checksum offset relative to
* checksum start.
*
* Csum start = Checksum start divided by two.
*
* http://tools.ietf.org/html/draft-herbert-vxlan-rco
*/
/* VXLAN-RCO header flags. */
#define VXLAN_HF_RCO cpu_to_be32(BIT(21))
/* Remote checksum offload header option */
#define VXLAN_RCO_MASK cpu_to_be32(0x7f) /* Last byte of vni field */
#define VXLAN_RCO_UDP cpu_to_be32(0x80) /* Indicate UDP RCO (TCP when not set *) */
#define VXLAN_RCO_SHIFT 1 /* Left shift of start */
#define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1)
#define VXLAN_MAX_REMCSUM_START (0x7f << VXLAN_RCO_SHIFT)
/*
* VXLAN Group Based Policy Extension (VXLAN_F_GBP):
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R| Group Policy ID |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* G = Group Policy ID present.
*
* D = Don't Learn bit. When set, this bit indicates that the egress
* VTEP MUST NOT learn the source address of the encapsulated frame.
*
@@ -27,18 +81,18 @@
* this packet. Policies MUST NOT be applied by devices when the
* A bit is set.
*
* [0] https://tools.ietf.org/html/draft-smith-vxlan-group-policy
* https://tools.ietf.org/html/draft-smith-vxlan-group-policy
*/
struct vxlanhdr_gbp {
__u8 vx_flags;
u8 vx_flags;
#ifdef __LITTLE_ENDIAN_BITFIELD
__u8 reserved_flags1:3,
u8 reserved_flags1:3,
policy_applied:1,
reserved_flags2:2,
dont_learn:1,
reserved_flags3:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 reserved_flags1:1,
u8 reserved_flags1:1,
dont_learn:1,
reserved_flags2:2,
policy_applied:1,
@@ -50,7 +104,10 @@ struct vxlanhdr_gbp {
__be32 vx_vni;
};
#define VXLAN_GBP_USED_BITS (VXLAN_HF_GBP | 0xFFFFFF)
/* VXLAN-GBP header flags. */
#define VXLAN_HF_GBP cpu_to_be32(BIT(31))
#define VXLAN_GBP_USED_BITS (VXLAN_HF_GBP | cpu_to_be32(0xFFFFFF))
/* skb->mark mapping
*
@@ -62,44 +119,6 @@ struct vxlanhdr_gbp {
#define VXLAN_GBP_POLICY_APPLIED (BIT(3) << 16)
#define VXLAN_GBP_ID_MASK (0xFFFF)
/* VXLAN protocol header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |G|R|R|R|I|R|R|C| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* G = 1 Group Policy (VXLAN-GBP)
* I = 1 VXLAN Network Identifier (VNI) present
* C = 1 Remote checksum offload (RCO)
*/
struct vxlanhdr {
__be32 vx_flags;
__be32 vx_vni;
};
/* VXLAN header flags. */
#define VXLAN_HF_RCO BIT(21)
#define VXLAN_HF_VNI BIT(27)
#define VXLAN_HF_GBP BIT(31)
/* Remote checksum offload header option */
#define VXLAN_RCO_MASK 0x7f /* Last byte of vni field */
#define VXLAN_RCO_UDP 0x80 /* Indicate UDP RCO (TCP when not set *) */
#define VXLAN_RCO_SHIFT 1 /* Left shift of start */
#define VXLAN_RCO_SHIFT_MASK ((1 << VXLAN_RCO_SHIFT) - 1)
#define VXLAN_MAX_REMCSUM_START (VXLAN_RCO_MASK << VXLAN_RCO_SHIFT)
#define VXLAN_N_VID (1u << 24)
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
#define VXLAN_VNI_MASK (VXLAN_VID_MASK << 8)
#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
#define VNI_HASH_BITS 10
#define VNI_HASH_SIZE (1<<VNI_HASH_BITS)
#define FDB_HASH_BITS 8
#define FDB_HASH_SIZE (1<<FDB_HASH_BITS)
struct vxlan_metadata {
u32 gbp;
};
@@ -125,23 +144,25 @@ union vxlan_addr {
struct vxlan_rdst {
union vxlan_addr remote_ip;
__be16 remote_port;
u32 remote_vni;
__be32 remote_vni;
u32 remote_ifindex;
struct list_head list;
struct rcu_head rcu;
struct dst_cache dst_cache;
};
struct vxlan_config {
union vxlan_addr remote_ip;
union vxlan_addr saddr;
u32 vni;
__be32 vni;
int remote_ifindex;
int mtu;
__be16 dst_port;
__u16 port_min;
__u16 port_max;
__u8 tos;
__u8 ttl;
u16 port_min;
u16 port_max;
u8 tos;
u8 ttl;
__be32 label;
u32 flags;
unsigned long age_interval;
unsigned int addrmax;
@@ -177,7 +198,7 @@ struct vxlan_dev {
#define VXLAN_F_L2MISS 0x08
#define VXLAN_F_L3MISS 0x10
#define VXLAN_F_IPV6 0x20
#define VXLAN_F_UDP_CSUM 0x40
#define VXLAN_F_UDP_ZERO_CSUM_TX 0x40
#define VXLAN_F_UDP_ZERO_CSUM6_TX 0x80
#define VXLAN_F_UDP_ZERO_CSUM6_RX 0x100
#define VXLAN_F_REMCSUM_TX 0x200
@@ -242,6 +263,68 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
/* IPv6 header + UDP + VXLAN + Ethernet header */
#define VXLAN6_HEADROOM (40 + 8 + 8 + 14)
static inline struct vxlanhdr *vxlan_hdr(struct sk_buff *skb)
{
return (struct vxlanhdr *)(udp_hdr(skb) + 1);
}
static inline __be32 vxlan_vni(__be32 vni_field)
{
#if defined(__BIG_ENDIAN)
return vni_field >> 8;
#else
return (vni_field & VXLAN_VNI_MASK) << 8;
#endif
}
static inline __be32 vxlan_vni_field(__be32 vni)
{
#if defined(__BIG_ENDIAN)
return vni << 8;
#else
return vni >> 8;
#endif
}
static inline __be32 vxlan_tun_id_to_vni(__be64 tun_id)
{
#if defined(__BIG_ENDIAN)
return tun_id;
#else
return tun_id >> 32;
#endif
}
static inline __be64 vxlan_vni_to_tun_id(__be32 vni)
{
#if defined(__BIG_ENDIAN)
return (__be64)vni;
#else
return (__be64)vni << 32;
#endif
}
static inline size_t vxlan_rco_start(__be32 vni_field)
{
return be32_to_cpu(vni_field & VXLAN_RCO_MASK) << VXLAN_RCO_SHIFT;
}
static inline size_t vxlan_rco_offset(__be32 vni_field)
{
return (vni_field & VXLAN_RCO_UDP) ?
offsetof(struct udphdr, check) :
offsetof(struct tcphdr, check);
}
static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
{
__be32 vni_field = cpu_to_be32(start >> VXLAN_RCO_SHIFT);
if (offset == offsetof(struct udphdr, check))
vni_field |= VXLAN_RCO_UDP;
return vni_field;
}
#if IS_ENABLED(CONFIG_VXLAN)
void vxlan_get_rx_port(struct net_device *netdev);
#else