Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cefd81cf authored by David S. Miller's avatar David S. Miller
Browse files
parents 3731a334 15eac2a7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+237 −138

File changed.

Preview size limit exceeded, changes collapsed.

+42 −8
Original line number Diff line number Diff line
@@ -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

/**
@@ -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.
@@ -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.
@@ -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;

+5 −3
Original line number Diff line number Diff line
@@ -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;
+4 −7
Original line number Diff line number Diff line
@@ -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);
@@ -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. */
@@ -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) {
@@ -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