lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e3e8fe54-019c-43ae-91bd-cb61ef1e5b18@redhat.com>
Date:   Mon, 7 Aug 2017 12:31:30 +0200
From:   Ivan Vecera <ivecera@...hat.com>
To:     Arkadi Sharshevsky <arkadis@...lanox.com>, netdev@...r.kernel.org
Cc:     davem@...emloft.net, jiri@...nulli.us, f.fainelli@...il.com,
        andrew@...n.ch, vivien.didelot@...oirfairelinux.com,
        Woojung.Huh@...rochip.com, mlxsw@...lanox.com
Subject: Re: [PATCH net-next v3 13/13] net: switchdev: Remove bridge bypass
 support from switchdev

On 6.8.2017 15:15, Arkadi Sharshevsky wrote:
> Currently the bridge port flags, vlans, FDBs and MDBs can be offloaded
> through the bridge code, making the switchdev's SELF bridge bypass
> implementation to be redundant. This implies several changes:
> - No need for dump infra in switchdev, DSA's special case is handled
>   privately.
> - Remove obj_dump from switchdev_ops.
> - FDBs are removed from obj_add/del routines, due to the fact that they
>   are offloaded through the bridge notification chain.
> - The switchdev_port_bridge_xx() and switchdev_port_fdb_xx() functions
>   can be removed.
> 
> Signed-off-by: Arkadi Sharshevsky <arkadis@...lanox.com>
> Reviewed-by: Vivien Didelot <vivien.didelot@...oirfairelinux.com>
> ---
> v1->v2
> - Fix typo in commit message.
> ---
>  include/net/switchdev.h   |  75 --------
>  net/switchdev/switchdev.c | 435 ----------------------------------------------
>  2 files changed, 510 deletions(-)
> 
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index d2637a6..d767b79 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -74,7 +74,6 @@ struct switchdev_attr {
>  enum switchdev_obj_id {
>  	SWITCHDEV_OBJ_ID_UNDEFINED,
>  	SWITCHDEV_OBJ_ID_PORT_VLAN,
> -	SWITCHDEV_OBJ_ID_PORT_FDB,
>  	SWITCHDEV_OBJ_ID_PORT_MDB,
>  };
>  
> @@ -97,17 +96,6 @@ struct switchdev_obj_port_vlan {
>  #define SWITCHDEV_OBJ_PORT_VLAN(obj) \
>  	container_of(obj, struct switchdev_obj_port_vlan, obj)
>  
> -/* SWITCHDEV_OBJ_ID_PORT_FDB */
> -struct switchdev_obj_port_fdb {
> -	struct switchdev_obj obj;
> -	unsigned char addr[ETH_ALEN];
> -	u16 vid;
> -	u16 ndm_state;
> -};
> -
> -#define SWITCHDEV_OBJ_PORT_FDB(obj) \
> -	container_of(obj, struct switchdev_obj_port_fdb, obj)
> -
>  /* SWITCHDEV_OBJ_ID_PORT_MDB */
>  struct switchdev_obj_port_mdb {
>  	struct switchdev_obj obj;
> @@ -135,8 +123,6 @@ typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
>   * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
>   *
>   * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
> - *
> - * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*).
>   */
>  struct switchdev_ops {
>  	int	(*switchdev_port_attr_get)(struct net_device *dev,
> @@ -149,9 +135,6 @@ struct switchdev_ops {
>  					  struct switchdev_trans *trans);
>  	int	(*switchdev_port_obj_del)(struct net_device *dev,
>  					  const struct switchdev_obj *obj);
> -	int	(*switchdev_port_obj_dump)(struct net_device *dev,
> -					   struct switchdev_obj *obj,
> -					   switchdev_obj_dump_cb_t *cb);
>  };
>  
>  enum switchdev_notifier_type {
> @@ -189,25 +172,10 @@ int switchdev_port_obj_add(struct net_device *dev,
>  			   const struct switchdev_obj *obj);
>  int switchdev_port_obj_del(struct net_device *dev,
>  			   const struct switchdev_obj *obj);
> -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj,
> -			    switchdev_obj_dump_cb_t *cb);
>  int register_switchdev_notifier(struct notifier_block *nb);
>  int unregister_switchdev_notifier(struct notifier_block *nb);
>  int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
>  			     struct switchdev_notifier_info *info);
> -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> -				  struct net_device *dev, u32 filter_mask,
> -				  int nlflags);
> -int switchdev_port_bridge_setlink(struct net_device *dev,
> -				  struct nlmsghdr *nlh, u16 flags);
> -int switchdev_port_bridge_dellink(struct net_device *dev,
> -				  struct nlmsghdr *nlh, u16 flags);
> -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> -			   struct net_device *dev, const unsigned char *addr,
> -			   u16 vid, u16 nlm_flags);
> -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
> -			   struct net_device *dev, const unsigned char *addr,
> -			   u16 vid);
>  void switchdev_port_fwd_mark_set(struct net_device *dev,
>  				 struct net_device *group_dev,
>  				 bool joining);
> @@ -246,13 +214,6 @@ static inline int switchdev_port_obj_del(struct net_device *dev,
>  	return -EOPNOTSUPP;
>  }
>  
> -static inline int switchdev_port_obj_dump(struct net_device *dev,
> -					  const struct switchdev_obj *obj,
> -					  switchdev_obj_dump_cb_t *cb)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
>  static inline int register_switchdev_notifier(struct notifier_block *nb)
>  {
>  	return 0;
> @@ -270,42 +231,6 @@ static inline int call_switchdev_notifiers(unsigned long val,
>  	return NOTIFY_DONE;
>  }
>  
> -static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
> -					    u32 seq, struct net_device *dev,
> -					    u32 filter_mask, int nlflags)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_bridge_setlink(struct net_device *dev,
> -						struct nlmsghdr *nlh,
> -						u16 flags)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_bridge_dellink(struct net_device *dev,
> -						struct nlmsghdr *nlh,
> -						u16 flags)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> -					 struct net_device *dev,
> -					 const unsigned char *addr,
> -					 u16 vid, u16 nlm_flags)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
> -					 struct net_device *dev,
> -					 const unsigned char *addr, u16 vid)
> -{
> -	return -EOPNOTSUPP;
> -}
> -
>  static inline bool switchdev_port_same_parent_id(struct net_device *a,
>  						 struct net_device *b)
>  {
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index 3d32981..0531b41 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -343,8 +343,6 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
>  	switch (obj->id) {
>  	case SWITCHDEV_OBJ_ID_PORT_VLAN:
>  		return sizeof(struct switchdev_obj_port_vlan);
> -	case SWITCHDEV_OBJ_ID_PORT_FDB:
> -		return sizeof(struct switchdev_obj_port_fdb);
>  	case SWITCHDEV_OBJ_ID_PORT_MDB:
>  		return sizeof(struct switchdev_obj_port_mdb);
>  	default:
> @@ -534,43 +532,6 @@ int switchdev_port_obj_del(struct net_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(switchdev_port_obj_del);
>  
> -/**
> - *	switchdev_port_obj_dump - Dump port objects
> - *
> - *	@dev: port device
> - *	@id: object ID
> - *	@obj: object to dump
> - *	@cb: function to call with a filled object
> - *
> - *	rtnl_lock must be held.
> - */
> -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj,
> -			    switchdev_obj_dump_cb_t *cb)
> -{
> -	const struct switchdev_ops *ops = dev->switchdev_ops;
> -	struct net_device *lower_dev;
> -	struct list_head *iter;
> -	int err = -EOPNOTSUPP;
> -
> -	ASSERT_RTNL();
> -
> -	if (ops && ops->switchdev_port_obj_dump)
> -		return ops->switchdev_port_obj_dump(dev, obj, cb);
> -
> -	/* Switch device port(s) may be stacked under
> -	 * bond/team/vlan dev, so recurse down to dump objects on
> -	 * first port at bottom of stack.
> -	 */
> -
> -	netdev_for_each_lower_dev(dev, lower_dev, iter) {
> -		err = switchdev_port_obj_dump(lower_dev, obj, cb);
> -		break;
> -	}
> -
> -	return err;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_obj_dump);
> -
>  static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
>  
>  /**
> @@ -613,402 +574,6 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
>  
> -struct switchdev_vlan_dump {
> -	struct switchdev_obj_port_vlan vlan;
> -	struct sk_buff *skb;
> -	u32 filter_mask;
> -	u16 flags;
> -	u16 begin;
> -	u16 end;
> -};
> -
> -static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump)
> -{
> -	struct bridge_vlan_info vinfo;
> -
> -	vinfo.flags = dump->flags;
> -
> -	if (dump->begin == 0 && dump->end == 0) {
> -		return 0;
> -	} else if (dump->begin == dump->end) {
> -		vinfo.vid = dump->begin;
> -		if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -			    sizeof(vinfo), &vinfo))
> -			return -EMSGSIZE;
> -	} else {
> -		vinfo.vid = dump->begin;
> -		vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
> -		if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -			    sizeof(vinfo), &vinfo))
> -			return -EMSGSIZE;
> -		vinfo.vid = dump->end;
> -		vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
> -		vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
> -		if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -			    sizeof(vinfo), &vinfo))
> -			return -EMSGSIZE;
> -	}
> -
> -	return 0;
> -}
> -
> -static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj)
> -{
> -	struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
> -	struct switchdev_vlan_dump *dump =
> -		container_of(vlan, struct switchdev_vlan_dump, vlan);
> -	int err = 0;
> -
> -	if (vlan->vid_begin > vlan->vid_end)
> -		return -EINVAL;
> -
> -	if (dump->filter_mask & RTEXT_FILTER_BRVLAN) {
> -		dump->flags = vlan->flags;
> -		for (dump->begin = dump->end = vlan->vid_begin;
> -		     dump->begin <= vlan->vid_end;
> -		     dump->begin++, dump->end++) {
> -			err = switchdev_port_vlan_dump_put(dump);
> -			if (err)
> -				return err;
> -		}
> -	} else if (dump->filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) {
> -		if (dump->begin > vlan->vid_begin &&
> -		    dump->begin >= vlan->vid_end) {
> -			if ((dump->begin - 1) == vlan->vid_end &&
> -			    dump->flags == vlan->flags) {
> -				/* prepend */
> -				dump->begin = vlan->vid_begin;
> -			} else {
> -				err = switchdev_port_vlan_dump_put(dump);
> -				dump->flags = vlan->flags;
> -				dump->begin = vlan->vid_begin;
> -				dump->end = vlan->vid_end;
> -			}
> -		} else if (dump->end <= vlan->vid_begin &&
> -		           dump->end < vlan->vid_end) {
> -			if ((dump->end  + 1) == vlan->vid_begin &&
> -			    dump->flags == vlan->flags) {
> -				/* append */
> -				dump->end = vlan->vid_end;
> -			} else {
> -				err = switchdev_port_vlan_dump_put(dump);
> -				dump->flags = vlan->flags;
> -				dump->begin = vlan->vid_begin;
> -				dump->end = vlan->vid_end;
> -			}
> -		} else {
> -			err = -EINVAL;
> -		}
> -	}
> -
> -	return err;
> -}
> -
> -static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device *dev,
> -				    u32 filter_mask)
> -{
> -	struct switchdev_vlan_dump dump = {
> -		.vlan.obj.orig_dev = dev,
> -		.vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
> -		.skb = skb,
> -		.filter_mask = filter_mask,
> -	};
> -	int err = 0;
> -
> -	if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
> -	    (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
> -		err = switchdev_port_obj_dump(dev, &dump.vlan.obj,
> -					      switchdev_port_vlan_dump_cb);
> -		if (err)
> -			goto err_out;
> -		if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
> -			/* last one */
> -			err = switchdev_port_vlan_dump_put(&dump);
> -	}
> -
> -err_out:
> -	return err == -EOPNOTSUPP ? 0 : err;
> -}
> -
> -/**
> - *	switchdev_port_bridge_getlink - Get bridge port attributes
> - *
> - *	@dev: port device
> - *
> - *	Called for SELF on rtnl_bridge_getlink to get bridge port
> - *	attributes.
> - */
> -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> -				  struct net_device *dev, u32 filter_mask,
> -				  int nlflags)
> -{
> -	struct switchdev_attr attr = {
> -		.orig_dev = dev,
> -		.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
> -	};
> -	u16 mode = BRIDGE_MODE_UNDEF;
> -	u32 mask = BR_LEARNING | BR_LEARNING_SYNC | BR_FLOOD;
> -	int err;
> -
> -	if (!netif_is_bridge_port(dev))
> -		return -EOPNOTSUPP;
> -
> -	err = switchdev_port_attr_get(dev, &attr);
> -	if (err && err != -EOPNOTSUPP)
> -		return err;
> -
> -	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode,
> -				       attr.u.brport_flags, mask, nlflags,
> -				       filter_mask, switchdev_port_vlan_fill);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink);
> -
> -static int switchdev_port_br_setflag(struct net_device *dev,
> -				     struct nlattr *nlattr,
> -				     unsigned long brport_flag)
> -{
> -	struct switchdev_attr attr = {
> -		.orig_dev = dev,
> -		.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
> -	};
> -	u8 flag = nla_get_u8(nlattr);
> -	int err;
> -
> -	err = switchdev_port_attr_get(dev, &attr);
> -	if (err)
> -		return err;
> -
> -	if (flag)
> -		attr.u.brport_flags |= brport_flag;
> -	else
> -		attr.u.brport_flags &= ~brport_flag;
> -
> -	return switchdev_port_attr_set(dev, &attr);
> -}
> -
> -static const struct nla_policy
> -switchdev_port_bridge_policy[IFLA_BRPORT_MAX + 1] = {
> -	[IFLA_BRPORT_STATE]		= { .type = NLA_U8 },
> -	[IFLA_BRPORT_COST]		= { .type = NLA_U32 },
> -	[IFLA_BRPORT_PRIORITY]		= { .type = NLA_U16 },
> -	[IFLA_BRPORT_MODE]		= { .type = NLA_U8 },
> -	[IFLA_BRPORT_GUARD]		= { .type = NLA_U8 },
> -	[IFLA_BRPORT_PROTECT]		= { .type = NLA_U8 },
> -	[IFLA_BRPORT_FAST_LEAVE]	= { .type = NLA_U8 },
> -	[IFLA_BRPORT_LEARNING]		= { .type = NLA_U8 },
> -	[IFLA_BRPORT_LEARNING_SYNC]	= { .type = NLA_U8 },
> -	[IFLA_BRPORT_UNICAST_FLOOD]	= { .type = NLA_U8 },
> -};
> -
> -static int switchdev_port_br_setlink_protinfo(struct net_device *dev,
> -					      struct nlattr *protinfo)
> -{
> -	struct nlattr *attr;
> -	int rem;
> -	int err;
> -
> -	err = nla_validate_nested(protinfo, IFLA_BRPORT_MAX,
> -				  switchdev_port_bridge_policy, NULL);
> -	if (err)
> -		return err;
> -
> -	nla_for_each_nested(attr, protinfo, rem) {
> -		switch (nla_type(attr)) {
> -		case IFLA_BRPORT_LEARNING:
> -			err = switchdev_port_br_setflag(dev, attr,
> -							BR_LEARNING);
> -			break;
> -		case IFLA_BRPORT_LEARNING_SYNC:
> -			err = switchdev_port_br_setflag(dev, attr,
> -							BR_LEARNING_SYNC);
> -			break;
> -		case IFLA_BRPORT_UNICAST_FLOOD:
> -			err = switchdev_port_br_setflag(dev, attr, BR_FLOOD);
> -			break;
> -		default:
> -			err = -EOPNOTSUPP;
> -			break;
> -		}
> -		if (err)
> -			return err;
> -	}
> -
> -	return 0;
> -}
> -
> -static int switchdev_port_br_afspec(struct net_device *dev,
> -				    struct nlattr *afspec,
> -				    int (*f)(struct net_device *dev,
> -					     const struct switchdev_obj *obj))
> -{
> -	struct nlattr *attr;
> -	struct bridge_vlan_info *vinfo;
> -	struct switchdev_obj_port_vlan vlan = {
> -		.obj.orig_dev = dev,
> -		.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
> -	};
> -	int rem;
> -	int err;
> -
> -	nla_for_each_nested(attr, afspec, rem) {
> -		if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO)
> -			continue;
> -		if (nla_len(attr) != sizeof(struct bridge_vlan_info))
> -			return -EINVAL;
> -		vinfo = nla_data(attr);
> -		if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
> -			return -EINVAL;
> -		vlan.flags = vinfo->flags;
> -		if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
> -			if (vlan.vid_begin)
> -				return -EINVAL;
> -			vlan.vid_begin = vinfo->vid;
> -			/* don't allow range of pvids */
> -			if (vlan.flags & BRIDGE_VLAN_INFO_PVID)
> -				return -EINVAL;
> -		} else if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) {
> -			if (!vlan.vid_begin)
> -				return -EINVAL;
> -			vlan.vid_end = vinfo->vid;
> -			if (vlan.vid_end <= vlan.vid_begin)
> -				return -EINVAL;
> -			err = f(dev, &vlan.obj);
> -			if (err)
> -				return err;
> -			vlan.vid_begin = 0;
> -		} else {
> -			if (vlan.vid_begin)
> -				return -EINVAL;
> -			vlan.vid_begin = vinfo->vid;
> -			vlan.vid_end = vinfo->vid;
> -			err = f(dev, &vlan.obj);
> -			if (err)
> -				return err;
> -			vlan.vid_begin = 0;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/**
> - *	switchdev_port_bridge_setlink - Set bridge port attributes
> - *
> - *	@dev: port device
> - *	@nlh: netlink header
> - *	@flags: netlink flags
> - *
> - *	Called for SELF on rtnl_bridge_setlink to set bridge port
> - *	attributes.
> - */
> -int switchdev_port_bridge_setlink(struct net_device *dev,
> -				  struct nlmsghdr *nlh, u16 flags)
> -{
> -	struct nlattr *protinfo;
> -	struct nlattr *afspec;
> -	int err = 0;
> -
> -	if (!netif_is_bridge_port(dev))
> -		return -EOPNOTSUPP;
> -
> -	protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -				   IFLA_PROTINFO);
> -	if (protinfo) {
> -		err = switchdev_port_br_setlink_protinfo(dev, protinfo);
> -		if (err)
> -			return err;
> -	}
> -
> -	afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -				 IFLA_AF_SPEC);
> -	if (afspec)
> -		err = switchdev_port_br_afspec(dev, afspec,
> -					       switchdev_port_obj_add);
> -
> -	return err;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_setlink);
> -
> -/**
> - *	switchdev_port_bridge_dellink - Set bridge port attributes
> - *
> - *	@dev: port device
> - *	@nlh: netlink header
> - *	@flags: netlink flags
> - *
> - *	Called for SELF on rtnl_bridge_dellink to set bridge port
> - *	attributes.
> - */
> -int switchdev_port_bridge_dellink(struct net_device *dev,
> -				  struct nlmsghdr *nlh, u16 flags)
> -{
> -	struct nlattr *afspec;
> -
> -	if (!netif_is_bridge_port(dev))
> -		return -EOPNOTSUPP;
> -
> -	afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -				 IFLA_AF_SPEC);
> -	if (afspec)
> -		return switchdev_port_br_afspec(dev, afspec,
> -						switchdev_port_obj_del);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_dellink);
> -
> -/**
> - *	switchdev_port_fdb_add - Add FDB (MAC/VLAN) entry to port
> - *
> - *	@ndmsg: netlink hdr
> - *	@nlattr: netlink attributes
> - *	@dev: port device
> - *	@addr: MAC address to add
> - *	@vid: VLAN to add
> - *
> - *	Add FDB entry to switch device.
> - */
> -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> -			   struct net_device *dev, const unsigned char *addr,
> -			   u16 vid, u16 nlm_flags)
> -{
> -	struct switchdev_obj_port_fdb fdb = {
> -		.obj.orig_dev = dev,
> -		.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
> -		.vid = vid,
> -	};
> -
> -	ether_addr_copy(fdb.addr, addr);
> -	return switchdev_port_obj_add(dev, &fdb.obj);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
> -
> -/**
> - *	switchdev_port_fdb_del - Delete FDB (MAC/VLAN) entry from port
> - *
> - *	@ndmsg: netlink hdr
> - *	@nlattr: netlink attributes
> - *	@dev: port device
> - *	@addr: MAC address to delete
> - *	@vid: VLAN to delete
> - *
> - *	Delete FDB entry from switch device.
> - */
> -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
> -			   struct net_device *dev, const unsigned char *addr,
> -			   u16 vid)
> -{
> -	struct switchdev_obj_port_fdb fdb = {
> -		.obj.orig_dev = dev,
> -		.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
> -		.vid = vid,
> -	};
> -
> -	ether_addr_copy(fdb.addr, addr);
> -	return switchdev_port_obj_del(dev, &fdb.obj);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
> -
>  bool switchdev_port_same_parent_id(struct net_device *a,
>  				   struct net_device *b)
>  {
> 

Reviewed-by: Ivan Vecera <ivecera@...hat.com>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ