brintos

brintos / linux-shallow public Read only

0
0
Text · 7.5 KiB · 76a351a Raw
251 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 *	Vxlan private header file4 *5 */6 7#ifndef _VXLAN_PRIVATE_H8#define _VXLAN_PRIVATE_H9 10#include <linux/rhashtable.h>11 12extern unsigned int vxlan_net_id;13extern const u8 all_zeros_mac[ETH_ALEN + 2];14extern const struct rhashtable_params vxlan_vni_rht_params;15 16#define PORT_HASH_BITS	817#define PORT_HASH_SIZE  (1 << PORT_HASH_BITS)18 19/* per-network namespace private data for this module */20struct vxlan_net {21	struct list_head  vxlan_list;22	struct hlist_head sock_list[PORT_HASH_SIZE];23	spinlock_t	  sock_lock;24	struct notifier_block nexthop_notifier_block;25};26 27/* Forwarding table entry */28struct vxlan_fdb {29	struct hlist_node hlist;	/* linked list of entries */30	struct rcu_head	  rcu;31	unsigned long	  updated;	/* jiffies */32	unsigned long	  used;33	struct list_head  remotes;34	u8		  eth_addr[ETH_ALEN];35	u16		  state;	/* see ndm_state */36	__be32		  vni;37	u16		  flags;	/* see ndm_flags and below */38	struct list_head  nh_list;39	struct nexthop __rcu *nh;40	struct vxlan_dev  __rcu *vdev;41};42 43#define NTF_VXLAN_ADDED_BY_USER 0x10044 45/* Virtual Network hash table head */46static inline struct hlist_head *vni_head(struct vxlan_sock *vs, __be32 vni)47{48	return &vs->vni_list[hash_32((__force u32)vni, VNI_HASH_BITS)];49}50 51/* Socket hash table head */52static inline struct hlist_head *vs_head(struct net *net, __be16 port)53{54	struct vxlan_net *vn = net_generic(net, vxlan_net_id);55 56	return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];57}58 59/* First remote destination for a forwarding entry.60 * Guaranteed to be non-NULL because remotes are never deleted.61 */62static inline struct vxlan_rdst *first_remote_rcu(struct vxlan_fdb *fdb)63{64	if (rcu_access_pointer(fdb->nh))65		return NULL;66	return list_entry_rcu(fdb->remotes.next, struct vxlan_rdst, list);67}68 69static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)70{71	if (rcu_access_pointer(fdb->nh))72		return NULL;73	return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);74}75 76#if IS_ENABLED(CONFIG_IPV6)77static inline78bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)79{80	if (a->sa.sa_family != b->sa.sa_family)81		return false;82	if (a->sa.sa_family == AF_INET6)83		return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);84	else85		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;86}87 88static inline int vxlan_nla_get_addr(union vxlan_addr *ip,89				     const struct nlattr *nla)90{91	if (nla_len(nla) >= sizeof(struct in6_addr)) {92		ip->sin6.sin6_addr = nla_get_in6_addr(nla);93		ip->sa.sa_family = AF_INET6;94		return 0;95	} else if (nla_len(nla) >= sizeof(__be32)) {96		ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);97		ip->sa.sa_family = AF_INET;98		return 0;99	} else {100		return -EAFNOSUPPORT;101	}102}103 104static inline int vxlan_nla_put_addr(struct sk_buff *skb, int attr,105				     const union vxlan_addr *ip)106{107	if (ip->sa.sa_family == AF_INET6)108		return nla_put_in6_addr(skb, attr, &ip->sin6.sin6_addr);109	else110		return nla_put_in_addr(skb, attr, ip->sin.sin_addr.s_addr);111}112 113static inline bool vxlan_addr_is_multicast(const union vxlan_addr *ip)114{115	if (ip->sa.sa_family == AF_INET6)116		return ipv6_addr_is_multicast(&ip->sin6.sin6_addr);117	else118		return ipv4_is_multicast(ip->sin.sin_addr.s_addr);119}120 121#else /* !CONFIG_IPV6 */122 123static inline124bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b)125{126	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;127}128 129static inline int vxlan_nla_get_addr(union vxlan_addr *ip,130				     const struct nlattr *nla)131{132	if (nla_len(nla) >= sizeof(struct in6_addr)) {133		return -EAFNOSUPPORT;134	} else if (nla_len(nla) >= sizeof(__be32)) {135		ip->sin.sin_addr.s_addr = nla_get_in_addr(nla);136		ip->sa.sa_family = AF_INET;137		return 0;138	} else {139		return -EAFNOSUPPORT;140	}141}142 143static inline int vxlan_nla_put_addr(struct sk_buff *skb, int attr,144				     const union vxlan_addr *ip)145{146	return nla_put_in_addr(skb, attr, ip->sin.sin_addr.s_addr);147}148 149static inline bool vxlan_addr_is_multicast(const union vxlan_addr *ip)150{151	return ipv4_is_multicast(ip->sin.sin_addr.s_addr);152}153 154#endif155 156static inline size_t vxlan_addr_size(const union vxlan_addr *ip)157{158	if (ip->sa.sa_family == AF_INET6)159		return sizeof(struct in6_addr);160	else161		return sizeof(__be32);162}163 164static inline struct vxlan_vni_node *165vxlan_vnifilter_lookup(struct vxlan_dev *vxlan, __be32 vni)166{167	struct vxlan_vni_group *vg;168 169	vg = rcu_dereference_rtnl(vxlan->vnigrp);170	if (!vg)171		return NULL;172 173	return rhashtable_lookup_fast(&vg->vni_hash, &vni,174				      vxlan_vni_rht_params);175}176 177/* vxlan_core.c */178int vxlan_fdb_create(struct vxlan_dev *vxlan,179		     const u8 *mac, union vxlan_addr *ip,180		     __u16 state, __be16 port, __be32 src_vni,181		     __be32 vni, __u32 ifindex, __u16 ndm_flags,182		     u32 nhid, struct vxlan_fdb **fdb,183		     struct netlink_ext_ack *extack);184int __vxlan_fdb_delete(struct vxlan_dev *vxlan,185		       const unsigned char *addr, union vxlan_addr ip,186		       __be16 port, __be32 src_vni, __be32 vni,187		       u32 ifindex, bool swdev_notify);188u32 eth_vni_hash(const unsigned char *addr, __be32 vni);189u32 fdb_head_index(struct vxlan_dev *vxlan, const u8 *mac, __be32 vni);190int vxlan_fdb_update(struct vxlan_dev *vxlan,191		     const u8 *mac, union vxlan_addr *ip,192		     __u16 state, __u16 flags,193		     __be16 port, __be32 src_vni, __be32 vni,194		     __u32 ifindex, __u16 ndm_flags, u32 nhid,195		     bool swdev_notify, struct netlink_ext_ack *extack);196void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,197		    __be32 default_vni, struct vxlan_rdst *rdst, bool did_rsc);198int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan,199		     struct vxlan_config *conf, __be32 vni);200 201/* vxlan_vnifilter.c */202int vxlan_vnigroup_init(struct vxlan_dev *vxlan);203void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);204 205int vxlan_vnifilter_init(void);206void vxlan_vnifilter_uninit(void);207void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,208			   struct vxlan_vni_node *vninode,209			   int type, unsigned int len);210 211void vxlan_vs_add_vnigrp(struct vxlan_dev *vxlan,212			 struct vxlan_sock *vs,213			 bool ipv6);214void vxlan_vs_del_vnigrp(struct vxlan_dev *vxlan);215int vxlan_vnilist_update_group(struct vxlan_dev *vxlan,216			       union vxlan_addr *old_remote_ip,217			       union vxlan_addr *new_remote_ip,218			       struct netlink_ext_ack *extack);219 220 221/* vxlan_multicast.c */222int vxlan_multicast_join(struct vxlan_dev *vxlan);223int vxlan_multicast_leave(struct vxlan_dev *vxlan);224bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev,225		      __be32 vni, union vxlan_addr *rip, int rifindex);226int vxlan_igmp_join(struct vxlan_dev *vxlan, union vxlan_addr *rip,227		    int rifindex);228int vxlan_igmp_leave(struct vxlan_dev *vxlan, union vxlan_addr *rip,229		     int rifindex);230 231/* vxlan_mdb.c */232int vxlan_mdb_dump(struct net_device *dev, struct sk_buff *skb,233		   struct netlink_callback *cb);234int vxlan_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags,235		  struct netlink_ext_ack *extack);236int vxlan_mdb_del(struct net_device *dev, struct nlattr *tb[],237		  struct netlink_ext_ack *extack);238int vxlan_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[],239		       struct netlink_ext_ack *extack);240int vxlan_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid,241		  u32 seq, struct netlink_ext_ack *extack);242struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,243						struct sk_buff *skb,244						__be32 src_vni);245netdev_tx_t vxlan_mdb_xmit(struct vxlan_dev *vxlan,246			   const struct vxlan_mdb_entry *mdb_entry,247			   struct sk_buff *skb);248int vxlan_mdb_init(struct vxlan_dev *vxlan);249void vxlan_mdb_fini(struct vxlan_dev *vxlan);250#endif251