Loading net/openvswitch/actions.c +1 −1 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port) if (unlikely(!skb)) return -ENOMEM; vport = rcu_dereference(dp->ports[out_port]); vport = ovs_vport_rcu(dp, out_port); if (unlikely(!vport)) { kfree_skb(skb); return -ENODEV; Loading net/openvswitch/datapath.c +237 −138 File changed.Preview size limit exceeded, changes collapsed. Show changes net/openvswitch/datapath.h +42 −8 Original line number Diff line number Diff line Loading @@ -27,10 +27,11 @@ #include <linux/u64_stats_sync.h> #include "flow.h" #include "vport.h" struct vport; #define DP_MAX_PORTS USHRT_MAX #define DP_VPORT_HASH_BUCKETS 1024 #define DP_MAX_PORTS 1024 #define SAMPLE_ACTION_DEPTH 3 /** Loading Loading @@ -58,11 +59,10 @@ struct dp_stats_percpu { * @list_node: Element in global 'dps' list. * @n_flows: Number of flows currently in flow table. * @table: Current flow table. Protected by genl_lock and RCU. * @ports: Map from port number to &struct vport. %OVSP_LOCAL port * always exists, other ports may be %NULL. Protected by RTNL and RCU. * @port_list: List of all ports in @ports in arbitrary order. RTNL required * to iterate or modify. * @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by * RTNL and RCU. * @stats_percpu: Per-CPU datapath statistics. * @net: Reference to net namespace. * * Context: See the comment on locking at the top of datapath.c for additional * locking information. Loading @@ -75,13 +75,37 @@ struct datapath { struct flow_table __rcu *table; /* Switch ports. */ struct vport __rcu *ports[DP_MAX_PORTS]; struct list_head port_list; struct hlist_head *ports; /* Stats. */ struct dp_stats_percpu __percpu *stats_percpu; #ifdef CONFIG_NET_NS /* Network namespace ref. */ struct net *net; #endif }; struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no); static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no) { WARN_ON_ONCE(!rcu_read_lock_held()); return ovs_lookup_vport(dp, port_no); } static inline struct vport *ovs_vport_rtnl_rcu(const struct datapath *dp, int port_no) { WARN_ON_ONCE(!rcu_read_lock_held() && !rtnl_is_locked()); return ovs_lookup_vport(dp, port_no); } static inline struct vport *ovs_vport_rtnl(const struct datapath *dp, int port_no) { ASSERT_RTNL(); return ovs_lookup_vport(dp, port_no); } /** * struct ovs_skb_cb - OVS data in skb CB * @flow: The flow associated with this packet. May be %NULL if no flow. Loading @@ -108,6 +132,16 @@ struct dp_upcall_info { u32 pid; }; static inline struct net *ovs_dp_get_net(struct datapath *dp) { return read_pnet(&dp->net); } static inline void ovs_dp_set_net(struct datapath *dp, struct net *net) { write_pnet(&dp->net, net); } extern struct notifier_block ovs_dp_device_notifier; extern struct genl_multicast_group ovs_dp_vport_multicast_group; Loading net/openvswitch/dp_notify.c +5 −3 Original line number Diff line number Diff line Loading @@ -41,18 +41,20 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UNREGISTER: if (!ovs_is_internal_dev(dev)) { struct sk_buff *notify; struct datapath *dp = vport->dp; notify = ovs_vport_cmd_build_info(vport, 0, 0, OVS_VPORT_CMD_DEL); ovs_dp_detach_port(vport); if (IS_ERR(notify)) { netlink_set_err(init_net.genl_sock, 0, netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0, ovs_dp_vport_multicast_group.id, PTR_ERR(notify)); break; } genlmsg_multicast(notify, 0, ovs_dp_vport_multicast_group.id, genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0, ovs_dp_vport_multicast_group.id, GFP_KERNEL); } break; Loading net/openvswitch/flow.c +4 −7 Original line number Diff line number Diff line Loading @@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions) int actions_len = nla_len(actions); struct sw_flow_actions *sfa; /* At least DP_MAX_PORTS actions are required to be able to flood a * packet to every port. Factor of 2 allows for setting VLAN tags, * etc. */ if (actions_len > 2 * DP_MAX_PORTS * nla_total_size(4)) if (actions_len > MAX_ACTIONS_BUFSIZE) return ERR_PTR(-EINVAL); sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); Loading Loading @@ -992,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, swkey->phy.in_port = in_port; attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); } else { swkey->phy.in_port = USHRT_MAX; swkey->phy.in_port = DP_MAX_PORTS; } /* Data attributes. */ Loading Loading @@ -1135,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, const struct nlattr *nla; int rem; *in_port = USHRT_MAX; *in_port = DP_MAX_PORTS; *priority = 0; nla_for_each_nested(nla, attr, rem) { Loading Loading @@ -1172,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) goto nla_put_failure; if (swkey->phy.in_port != USHRT_MAX && if (swkey->phy.in_port != DP_MAX_PORTS && nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) goto nla_put_failure; Loading Loading
net/openvswitch/actions.c +1 −1 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port) if (unlikely(!skb)) return -ENOMEM; vport = rcu_dereference(dp->ports[out_port]); vport = ovs_vport_rcu(dp, out_port); if (unlikely(!vport)) { kfree_skb(skb); return -ENODEV; Loading
net/openvswitch/datapath.c +237 −138 File changed.Preview size limit exceeded, changes collapsed. Show changes
net/openvswitch/datapath.h +42 −8 Original line number Diff line number Diff line Loading @@ -27,10 +27,11 @@ #include <linux/u64_stats_sync.h> #include "flow.h" #include "vport.h" struct vport; #define DP_MAX_PORTS USHRT_MAX #define DP_VPORT_HASH_BUCKETS 1024 #define DP_MAX_PORTS 1024 #define SAMPLE_ACTION_DEPTH 3 /** Loading Loading @@ -58,11 +59,10 @@ struct dp_stats_percpu { * @list_node: Element in global 'dps' list. * @n_flows: Number of flows currently in flow table. * @table: Current flow table. Protected by genl_lock and RCU. * @ports: Map from port number to &struct vport. %OVSP_LOCAL port * always exists, other ports may be %NULL. Protected by RTNL and RCU. * @port_list: List of all ports in @ports in arbitrary order. RTNL required * to iterate or modify. * @ports: Hash table for ports. %OVSP_LOCAL port always exists. Protected by * RTNL and RCU. * @stats_percpu: Per-CPU datapath statistics. * @net: Reference to net namespace. * * Context: See the comment on locking at the top of datapath.c for additional * locking information. Loading @@ -75,13 +75,37 @@ struct datapath { struct flow_table __rcu *table; /* Switch ports. */ struct vport __rcu *ports[DP_MAX_PORTS]; struct list_head port_list; struct hlist_head *ports; /* Stats. */ struct dp_stats_percpu __percpu *stats_percpu; #ifdef CONFIG_NET_NS /* Network namespace ref. */ struct net *net; #endif }; struct vport *ovs_lookup_vport(const struct datapath *dp, u16 port_no); static inline struct vport *ovs_vport_rcu(const struct datapath *dp, int port_no) { WARN_ON_ONCE(!rcu_read_lock_held()); return ovs_lookup_vport(dp, port_no); } static inline struct vport *ovs_vport_rtnl_rcu(const struct datapath *dp, int port_no) { WARN_ON_ONCE(!rcu_read_lock_held() && !rtnl_is_locked()); return ovs_lookup_vport(dp, port_no); } static inline struct vport *ovs_vport_rtnl(const struct datapath *dp, int port_no) { ASSERT_RTNL(); return ovs_lookup_vport(dp, port_no); } /** * struct ovs_skb_cb - OVS data in skb CB * @flow: The flow associated with this packet. May be %NULL if no flow. Loading @@ -108,6 +132,16 @@ struct dp_upcall_info { u32 pid; }; static inline struct net *ovs_dp_get_net(struct datapath *dp) { return read_pnet(&dp->net); } static inline void ovs_dp_set_net(struct datapath *dp, struct net *net) { write_pnet(&dp->net, net); } extern struct notifier_block ovs_dp_device_notifier; extern struct genl_multicast_group ovs_dp_vport_multicast_group; Loading
net/openvswitch/dp_notify.c +5 −3 Original line number Diff line number Diff line Loading @@ -41,18 +41,20 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UNREGISTER: if (!ovs_is_internal_dev(dev)) { struct sk_buff *notify; struct datapath *dp = vport->dp; notify = ovs_vport_cmd_build_info(vport, 0, 0, OVS_VPORT_CMD_DEL); ovs_dp_detach_port(vport); if (IS_ERR(notify)) { netlink_set_err(init_net.genl_sock, 0, netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0, ovs_dp_vport_multicast_group.id, PTR_ERR(notify)); break; } genlmsg_multicast(notify, 0, ovs_dp_vport_multicast_group.id, genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0, ovs_dp_vport_multicast_group.id, GFP_KERNEL); } break; Loading
net/openvswitch/flow.c +4 −7 Original line number Diff line number Diff line Loading @@ -203,10 +203,7 @@ struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions) int actions_len = nla_len(actions); struct sw_flow_actions *sfa; /* At least DP_MAX_PORTS actions are required to be able to flood a * packet to every port. Factor of 2 allows for setting VLAN tags, * etc. */ if (actions_len > 2 * DP_MAX_PORTS * nla_total_size(4)) if (actions_len > MAX_ACTIONS_BUFSIZE) return ERR_PTR(-EINVAL); sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL); Loading Loading @@ -992,7 +989,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, swkey->phy.in_port = in_port; attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT); } else { swkey->phy.in_port = USHRT_MAX; swkey->phy.in_port = DP_MAX_PORTS; } /* Data attributes. */ Loading Loading @@ -1135,7 +1132,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, const struct nlattr *nla; int rem; *in_port = USHRT_MAX; *in_port = DP_MAX_PORTS; *priority = 0; nla_for_each_nested(nla, attr, rem) { Loading Loading @@ -1172,7 +1169,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) goto nla_put_failure; if (swkey->phy.in_port != USHRT_MAX && if (swkey->phy.in_port != DP_MAX_PORTS && nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) goto nla_put_failure; Loading