diff options
Diffstat (limited to 'net/openvswitch')
| -rw-r--r-- | net/openvswitch/Kconfig | 11 | ||||
| -rw-r--r-- | net/openvswitch/Makefile | 4 | ||||
| -rw-r--r-- | net/openvswitch/actions.c | 5 | ||||
| -rw-r--r-- | net/openvswitch/datapath.c | 44 | ||||
| -rw-r--r-- | net/openvswitch/datapath.h | 2 | ||||
| -rw-r--r-- | net/openvswitch/flow.c | 76 | ||||
| -rw-r--r-- | net/openvswitch/flow.h | 48 | ||||
| -rw-r--r-- | net/openvswitch/flow_netlink.c | 227 | ||||
| -rw-r--r-- | net/openvswitch/vport-geneve.c | 236 | ||||
| -rw-r--r-- | net/openvswitch/vport-gre.c | 16 | ||||
| -rw-r--r-- | net/openvswitch/vport-vxlan.c | 10 | ||||
| -rw-r--r-- | net/openvswitch/vport.c | 9 | ||||
| -rw-r--r-- | net/openvswitch/vport.h | 3 |
13 files changed, 599 insertions, 92 deletions
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 6ecf491ad509..ba3bb8203b99 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig | |||
| @@ -54,3 +54,14 @@ config OPENVSWITCH_VXLAN | |||
| 54 | Say N to exclude this support and reduce the binary size. | 54 | Say N to exclude this support and reduce the binary size. |
| 55 | 55 | ||
| 56 | If unsure, say Y. | 56 | If unsure, say Y. |
| 57 | |||
| 58 | config OPENVSWITCH_GENEVE | ||
| 59 | bool "Open vSwitch Geneve tunneling support" | ||
| 60 | depends on INET | ||
| 61 | depends on OPENVSWITCH | ||
| 62 | depends on GENEVE && !(OPENVSWITCH=y && GENEVE=m) | ||
| 63 | default y | ||
| 64 | ---help--- | ||
| 65 | If you say Y here, then the Open vSwitch will be able create geneve vport. | ||
| 66 | |||
| 67 | Say N to exclude this support and reduce the binary size. | ||
diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile index 3591cb5dae91..9a33a273c375 100644 --- a/net/openvswitch/Makefile +++ b/net/openvswitch/Makefile | |||
| @@ -15,6 +15,10 @@ openvswitch-y := \ | |||
| 15 | vport-internal_dev.o \ | 15 | vport-internal_dev.o \ |
| 16 | vport-netdev.o | 16 | vport-netdev.o |
| 17 | 17 | ||
| 18 | ifneq ($(CONFIG_OPENVSWITCH_GENEVE),) | ||
| 19 | openvswitch-y += vport-geneve.o | ||
| 20 | endif | ||
| 21 | |||
| 18 | ifneq ($(CONFIG_OPENVSWITCH_VXLAN),) | 22 | ifneq ($(CONFIG_OPENVSWITCH_VXLAN),) |
| 19 | openvswitch-y += vport-vxlan.o | 23 | openvswitch-y += vport-vxlan.o |
| 20 | endif | 24 | endif |
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 6932a42e41a2..006886dbee36 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
| @@ -590,8 +590,8 @@ static int execute_set_action(struct sk_buff *skb, | |||
| 590 | skb->mark = nla_get_u32(nested_attr); | 590 | skb->mark = nla_get_u32(nested_attr); |
| 591 | break; | 591 | break; |
| 592 | 592 | ||
| 593 | case OVS_KEY_ATTR_IPV4_TUNNEL: | 593 | case OVS_KEY_ATTR_TUNNEL_INFO: |
| 594 | OVS_CB(skb)->egress_tun_key = nla_data(nested_attr); | 594 | OVS_CB(skb)->egress_tun_info = nla_data(nested_attr); |
| 595 | break; | 595 | break; |
| 596 | 596 | ||
| 597 | case OVS_KEY_ATTR_ETHERNET: | 597 | case OVS_KEY_ATTR_ETHERNET: |
| @@ -778,6 +778,7 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
| 778 | acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); | 778 | acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); |
| 779 | 779 | ||
| 780 | this_cpu_inc(exec_actions_level); | 780 | this_cpu_inc(exec_actions_level); |
| 781 | OVS_CB(skb)->egress_tun_info = NULL; | ||
| 781 | err = do_execute_actions(dp, skb, key, | 782 | err = do_execute_actions(dp, skb, key, |
| 782 | acts->actions, acts->actions_len); | 783 | acts->actions, acts->actions_len); |
| 783 | 784 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 9e3a2fae6a8f..2e31d9e7f4dc 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -369,6 +369,8 @@ static size_t key_attr_size(void) | |||
| 369 | + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */ | 369 | + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */ |
| 370 | + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */ | 370 | + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */ |
| 371 | + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */ | 371 | + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */ |
| 372 | + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */ | ||
| 373 | + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */ | ||
| 372 | + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */ | 374 | + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */ |
| 373 | + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */ | 375 | + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */ |
| 374 | + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */ | 376 | + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */ |
| @@ -555,10 +557,12 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) | |||
| 555 | 557 | ||
| 556 | err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], | 558 | err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], |
| 557 | &flow->key, 0, &acts); | 559 | &flow->key, 0, &acts); |
| 558 | rcu_assign_pointer(flow->sf_acts, acts); | ||
| 559 | if (err) | 560 | if (err) |
| 560 | goto err_flow_free; | 561 | goto err_flow_free; |
| 561 | 562 | ||
| 563 | rcu_assign_pointer(flow->sf_acts, acts); | ||
| 564 | |||
| 565 | OVS_CB(packet)->egress_tun_info = NULL; | ||
| 562 | OVS_CB(packet)->flow = flow; | 566 | OVS_CB(packet)->flow = flow; |
| 563 | packet->priority = flow->key.phy.priority; | 567 | packet->priority = flow->key.phy.priority; |
| 564 | packet->mark = flow->key.phy.skb_mark; | 568 | packet->mark = flow->key.phy.skb_mark; |
| @@ -932,11 +936,34 @@ error: | |||
| 932 | return error; | 936 | return error; |
| 933 | } | 937 | } |
| 934 | 938 | ||
| 939 | static struct sw_flow_actions *get_flow_actions(const struct nlattr *a, | ||
| 940 | const struct sw_flow_key *key, | ||
| 941 | const struct sw_flow_mask *mask) | ||
| 942 | { | ||
| 943 | struct sw_flow_actions *acts; | ||
| 944 | struct sw_flow_key masked_key; | ||
| 945 | int error; | ||
| 946 | |||
| 947 | acts = ovs_nla_alloc_flow_actions(nla_len(a)); | ||
| 948 | if (IS_ERR(acts)) | ||
| 949 | return acts; | ||
| 950 | |||
| 951 | ovs_flow_mask_key(&masked_key, key, mask); | ||
| 952 | error = ovs_nla_copy_actions(a, &masked_key, 0, &acts); | ||
| 953 | if (error) { | ||
| 954 | OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); | ||
| 955 | kfree(acts); | ||
| 956 | return ERR_PTR(error); | ||
| 957 | } | ||
| 958 | |||
| 959 | return acts; | ||
| 960 | } | ||
| 961 | |||
| 935 | static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) | 962 | static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) |
| 936 | { | 963 | { |
| 937 | struct nlattr **a = info->attrs; | 964 | struct nlattr **a = info->attrs; |
| 938 | struct ovs_header *ovs_header = info->userhdr; | 965 | struct ovs_header *ovs_header = info->userhdr; |
| 939 | struct sw_flow_key key, masked_key; | 966 | struct sw_flow_key key; |
| 940 | struct sw_flow *flow; | 967 | struct sw_flow *flow; |
| 941 | struct sw_flow_mask mask; | 968 | struct sw_flow_mask mask; |
| 942 | struct sk_buff *reply = NULL; | 969 | struct sk_buff *reply = NULL; |
| @@ -958,17 +985,10 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
| 958 | 985 | ||
| 959 | /* Validate actions. */ | 986 | /* Validate actions. */ |
| 960 | if (a[OVS_FLOW_ATTR_ACTIONS]) { | 987 | if (a[OVS_FLOW_ATTR_ACTIONS]) { |
| 961 | acts = ovs_nla_alloc_flow_actions(nla_len(a[OVS_FLOW_ATTR_ACTIONS])); | 988 | acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask); |
| 962 | error = PTR_ERR(acts); | 989 | if (IS_ERR(acts)) { |
| 963 | if (IS_ERR(acts)) | 990 | error = PTR_ERR(acts); |
| 964 | goto error; | 991 | goto error; |
| 965 | |||
| 966 | ovs_flow_mask_key(&masked_key, &key, &mask); | ||
| 967 | error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], | ||
| 968 | &masked_key, 0, &acts); | ||
| 969 | if (error) { | ||
| 970 | OVS_NLERR("Flow actions may not be safe on all matching packets.\n"); | ||
| 971 | goto err_kfree_acts; | ||
| 972 | } | 992 | } |
| 973 | } | 993 | } |
| 974 | 994 | ||
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index ac3f3df96961..974135439c5c 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
| @@ -102,8 +102,8 @@ struct datapath { | |||
| 102 | */ | 102 | */ |
| 103 | struct ovs_skb_cb { | 103 | struct ovs_skb_cb { |
| 104 | struct sw_flow *flow; | 104 | struct sw_flow *flow; |
| 105 | struct ovs_tunnel_info *egress_tun_info; | ||
| 105 | struct vport *input_vport; | 106 | struct vport *input_vport; |
| 106 | struct ovs_key_ipv4_tunnel *egress_tun_key; | ||
| 107 | }; | 107 | }; |
| 108 | #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) | 108 | #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) |
| 109 | 109 | ||
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 4010423f2831..62db02ba36bc 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
| @@ -448,6 +448,9 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
| 448 | int error; | 448 | int error; |
| 449 | struct ethhdr *eth; | 449 | struct ethhdr *eth; |
| 450 | 450 | ||
| 451 | /* Flags are always used as part of stats */ | ||
