diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r-- | net/openvswitch/datapath.c | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 9db4bf6740d1..7228ec3faf19 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -47,8 +47,6 @@ | |||
47 | #include <linux/openvswitch.h> | 47 | #include <linux/openvswitch.h> |
48 | #include <linux/rculist.h> | 48 | #include <linux/rculist.h> |
49 | #include <linux/dmi.h> | 49 | #include <linux/dmi.h> |
50 | #include <linux/genetlink.h> | ||
51 | #include <net/genetlink.h> | ||
52 | #include <net/genetlink.h> | 50 | #include <net/genetlink.h> |
53 | #include <net/net_namespace.h> | 51 | #include <net/net_namespace.h> |
54 | #include <net/netns/generic.h> | 52 | #include <net/netns/generic.h> |
@@ -66,16 +64,16 @@ static struct genl_family dp_packet_genl_family; | |||
66 | static struct genl_family dp_flow_genl_family; | 64 | static struct genl_family dp_flow_genl_family; |
67 | static struct genl_family dp_datapath_genl_family; | 65 | static struct genl_family dp_datapath_genl_family; |
68 | 66 | ||
69 | static struct genl_multicast_group ovs_dp_flow_multicast_group = { | 67 | static const struct genl_multicast_group ovs_dp_flow_multicast_group = { |
70 | .name = OVS_FLOW_MCGROUP | 68 | .name = OVS_FLOW_MCGROUP, |
71 | }; | 69 | }; |
72 | 70 | ||
73 | static struct genl_multicast_group ovs_dp_datapath_multicast_group = { | 71 | static const struct genl_multicast_group ovs_dp_datapath_multicast_group = { |
74 | .name = OVS_DATAPATH_MCGROUP | 72 | .name = OVS_DATAPATH_MCGROUP, |
75 | }; | 73 | }; |
76 | 74 | ||
77 | struct genl_multicast_group ovs_dp_vport_multicast_group = { | 75 | static const struct genl_multicast_group ovs_dp_vport_multicast_group = { |
78 | .name = OVS_VPORT_MCGROUP | 76 | .name = OVS_VPORT_MCGROUP, |
79 | }; | 77 | }; |
80 | 78 | ||
81 | /* Check if need to build a reply message. | 79 | /* Check if need to build a reply message. |
@@ -266,7 +264,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) | |||
266 | upcall.cmd = OVS_PACKET_CMD_MISS; | 264 | upcall.cmd = OVS_PACKET_CMD_MISS; |
267 | upcall.key = &key; | 265 | upcall.key = &key; |
268 | upcall.userdata = NULL; | 266 | upcall.userdata = NULL; |
269 | upcall.portid = p->upcall_portid; | 267 | upcall.portid = ovs_vport_find_upcall_portid(p, skb); |
270 | ovs_dp_upcall(dp, skb, &upcall); | 268 | ovs_dp_upcall(dp, skb, &upcall); |
271 | consume_skb(skb); | 269 | consume_skb(skb); |
272 | stats_counter = &stats->n_missed; | 270 | stats_counter = &stats->n_missed; |
@@ -464,7 +462,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
464 | upcall->dp_ifindex = dp_ifindex; | 462 | upcall->dp_ifindex = dp_ifindex; |
465 | 463 | ||
466 | nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); | 464 | nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); |
467 | ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb); | 465 | err = ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb); |
466 | BUG_ON(err); | ||
468 | nla_nest_end(user_skb, nla); | 467 | nla_nest_end(user_skb, nla); |
469 | 468 | ||
470 | if (upcall_info->userdata) | 469 | if (upcall_info->userdata) |
@@ -780,7 +779,7 @@ static struct sk_buff *ovs_flow_cmd_build_info(const struct sw_flow *flow, | |||
780 | 779 | ||
781 | skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info, | 780 | skb = ovs_flow_cmd_alloc_info(ovsl_dereference(flow->sf_acts), info, |
782 | always); | 781 | always); |
783 | if (!skb || IS_ERR(skb)) | 782 | if (IS_ERR_OR_NULL(skb)) |
784 | return skb; | 783 | return skb; |
785 | 784 | ||
786 | retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, | 785 | retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, |
@@ -1189,7 +1188,7 @@ static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = { | |||
1189 | [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, | 1188 | [OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG }, |
1190 | }; | 1189 | }; |
1191 | 1190 | ||
1192 | static struct genl_ops dp_flow_genl_ops[] = { | 1191 | static const struct genl_ops dp_flow_genl_ops[] = { |
1193 | { .cmd = OVS_FLOW_CMD_NEW, | 1192 | { .cmd = OVS_FLOW_CMD_NEW, |
1194 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ | 1193 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ |
1195 | .policy = flow_policy, | 1194 | .policy = flow_policy, |
@@ -1373,7 +1372,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1373 | parms.options = NULL; | 1372 | parms.options = NULL; |
1374 | parms.dp = dp; | 1373 | parms.dp = dp; |
1375 | parms.port_no = OVSP_LOCAL; | 1374 | parms.port_no = OVSP_LOCAL; |
1376 | parms.upcall_portid = nla_get_u32(a[OVS_DP_ATTR_UPCALL_PID]); | 1375 | parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID]; |
1377 | 1376 | ||
1378 | ovs_dp_change(dp, a); | 1377 | ovs_dp_change(dp, a); |
1379 | 1378 | ||
@@ -1577,7 +1576,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = { | |||
1577 | [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, | 1576 | [OVS_DP_ATTR_USER_FEATURES] = { .type = NLA_U32 }, |
1578 | }; | 1577 | }; |
1579 | 1578 | ||
1580 | static struct genl_ops dp_datapath_genl_ops[] = { | 1579 | static const struct genl_ops dp_datapath_genl_ops[] = { |
1581 | { .cmd = OVS_DP_CMD_NEW, | 1580 | { .cmd = OVS_DP_CMD_NEW, |
1582 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ | 1581 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ |
1583 | .policy = datapath_policy, | 1582 | .policy = datapath_policy, |
@@ -1632,8 +1631,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, | |||
1632 | 1631 | ||
1633 | if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) || | 1632 | if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) || |
1634 | nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) || | 1633 | nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) || |
1635 | nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) || | 1634 | nla_put_string(skb, OVS_VPORT_ATTR_NAME, |
1636 | nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_portid)) | 1635 | vport->ops->get_name(vport))) |
1637 | goto nla_put_failure; | 1636 | goto nla_put_failure; |
1638 | 1637 | ||
1639 | ovs_vport_get_stats(vport, &vport_stats); | 1638 | ovs_vport_get_stats(vport, &vport_stats); |
@@ -1641,6 +1640,9 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, | |||
1641 | &vport_stats)) | 1640 | &vport_stats)) |
1642 | goto nla_put_failure; | 1641 | goto nla_put_failure; |
1643 | 1642 | ||
1643 | if (ovs_vport_get_upcall_portids(vport, skb)) | ||
1644 | goto nla_put_failure; | ||
1645 | |||
1644 | err = ovs_vport_get_options(vport, skb); | 1646 | err = ovs_vport_get_options(vport, skb); |
1645 | if (err == -EMSGSIZE) | 1647 | if (err == -EMSGSIZE) |
1646 | goto error; | 1648 | goto error; |
@@ -1762,7 +1764,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) | |||
1762 | parms.options = a[OVS_VPORT_ATTR_OPTIONS]; | 1764 | parms.options = a[OVS_VPORT_ATTR_OPTIONS]; |
1763 | parms.dp = dp; | 1765 | parms.dp = dp; |
1764 | parms.port_no = port_no; | 1766 | parms.port_no = port_no; |
1765 | parms.upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); | 1767 | parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID]; |
1766 | 1768 | ||
1767 | vport = new_vport(&parms); | 1769 | vport = new_vport(&parms); |
1768 | err = PTR_ERR(vport); | 1770 | err = PTR_ERR(vport); |
@@ -1812,8 +1814,14 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
1812 | goto exit_unlock_free; | 1814 | goto exit_unlock_free; |
1813 | } | 1815 | } |
1814 | 1816 | ||
1815 | if (a[OVS_VPORT_ATTR_UPCALL_PID]) | 1817 | |
1816 | vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); | 1818 | if (a[OVS_VPORT_ATTR_UPCALL_PID]) { |
1819 | struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID]; | ||
1820 | |||
1821 | err = ovs_vport_set_upcall_portids(vport, ids); | ||
1822 | if (err) | ||
1823 | goto exit_unlock_free; | ||
1824 | } | ||
1817 | 1825 | ||
1818 | err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, | 1826 | err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, |
1819 | info->snd_seq, 0, OVS_VPORT_CMD_NEW); | 1827 | info->snd_seq, 0, OVS_VPORT_CMD_NEW); |
@@ -1944,7 +1952,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = { | |||
1944 | [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, | 1952 | [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, |
1945 | }; | 1953 | }; |
1946 | 1954 | ||
1947 | static struct genl_ops dp_vport_genl_ops[] = { | 1955 | static const struct genl_ops dp_vport_genl_ops[] = { |
1948 | { .cmd = OVS_VPORT_CMD_NEW, | 1956 | { .cmd = OVS_VPORT_CMD_NEW, |
1949 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ | 1957 | .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */ |
1950 | .policy = vport_policy, | 1958 | .policy = vport_policy, |
@@ -2053,10 +2061,14 @@ static int __init dp_init(void) | |||
2053 | 2061 | ||
2054 | pr_info("Open vSwitch switching datapath\n"); | 2062 | pr_info("Open vSwitch switching datapath\n"); |
2055 | 2063 | ||
2056 | err = ovs_flow_init(); | 2064 | err = ovs_internal_dev_rtnl_link_register(); |
2057 | if (err) | 2065 | if (err) |
2058 | goto error; | 2066 | goto error; |
2059 | 2067 | ||
2068 | err = ovs_flow_init(); | ||
2069 | if (err) | ||
2070 | goto error_unreg_rtnl_link; | ||
2071 | |||
2060 | err = ovs_vport_init(); | 2072 | err = ovs_vport_init(); |
2061 | if (err) | 2073 | if (err) |
2062 | goto error_flow_exit; | 2074 | goto error_flow_exit; |
@@ -2083,6 +2095,8 @@ error_vport_exit: | |||
2083 | ovs_vport_exit(); | 2095 | ovs_vport_exit(); |
2084 | error_flow_exit: | 2096 | error_flow_exit: |
2085 | ovs_flow_exit(); | 2097 | ovs_flow_exit(); |
2098 | error_unreg_rtnl_link: | ||
2099 | ovs_internal_dev_rtnl_link_unregister(); | ||
2086 | error: | 2100 | error: |
2087 | return err; | 2101 | return err; |
2088 | } | 2102 | } |
@@ -2095,6 +2109,7 @@ static void dp_cleanup(void) | |||
2095 | rcu_barrier(); | 2109 | rcu_barrier(); |
2096 | ovs_vport_exit(); | 2110 | ovs_vport_exit(); |
2097 | ovs_flow_exit(); | 2111 | ovs_flow_exit(); |
2112 | ovs_internal_dev_rtnl_link_unregister(); | ||
2098 | } | 2113 | } |
2099 | 2114 | ||
2100 | module_init(dp_init); | 2115 | module_init(dp_init); |