diff options
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r-- | net/openvswitch/flow_netlink.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 22c855fa0bc2..5d6194d9dadc 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -1148,13 +1148,14 @@ out: | |||
1148 | return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset); | 1148 | return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, int len) | 1151 | static struct nlattr *__add_action(struct sw_flow_actions **sfa, |
1152 | int attrtype, void *data, int len) | ||
1152 | { | 1153 | { |
1153 | struct nlattr *a; | 1154 | struct nlattr *a; |
1154 | 1155 | ||
1155 | a = reserve_sfa_size(sfa, nla_attr_size(len)); | 1156 | a = reserve_sfa_size(sfa, nla_attr_size(len)); |
1156 | if (IS_ERR(a)) | 1157 | if (IS_ERR(a)) |
1157 | return PTR_ERR(a); | 1158 | return a; |
1158 | 1159 | ||
1159 | a->nla_type = attrtype; | 1160 | a->nla_type = attrtype; |
1160 | a->nla_len = nla_attr_size(len); | 1161 | a->nla_len = nla_attr_size(len); |
@@ -1163,6 +1164,18 @@ static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, in | |||
1163 | memcpy(nla_data(a), data, len); | 1164 | memcpy(nla_data(a), data, len); |
1164 | memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len)); | 1165 | memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len)); |
1165 | 1166 | ||
1167 | return a; | ||
1168 | } | ||
1169 | |||
1170 | static int add_action(struct sw_flow_actions **sfa, int attrtype, | ||
1171 | void *data, int len) | ||
1172 | { | ||
1173 | struct nlattr *a; | ||
1174 | |||
1175 | a = __add_action(sfa, attrtype, data, len); | ||
1176 | if (IS_ERR(a)) | ||
1177 | return PTR_ERR(a); | ||
1178 | |||
1166 | return 0; | 1179 | return 0; |
1167 | } | 1180 | } |
1168 | 1181 | ||
@@ -1268,6 +1281,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
1268 | { | 1281 | { |
1269 | struct sw_flow_match match; | 1282 | struct sw_flow_match match; |
1270 | struct sw_flow_key key; | 1283 | struct sw_flow_key key; |
1284 | struct ovs_tunnel_info *tun_info; | ||
1285 | struct nlattr *a; | ||
1271 | int err, start; | 1286 | int err, start; |
1272 | 1287 | ||
1273 | ovs_match_init(&match, &key, NULL); | 1288 | ovs_match_init(&match, &key, NULL); |
@@ -1279,8 +1294,14 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
1279 | if (start < 0) | 1294 | if (start < 0) |
1280 | return start; | 1295 | return start; |
1281 | 1296 | ||
1282 | err = add_action(sfa, OVS_KEY_ATTR_IPV4_TUNNEL, &match.key->tun_key, | 1297 | a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL, |
1283 | sizeof(match.key->tun_key)); | 1298 | sizeof(*tun_info)); |
1299 | if (IS_ERR(a)) | ||
1300 | return PTR_ERR(a); | ||
1301 | |||
1302 | tun_info = nla_data(a); | ||
1303 | tun_info->tunnel = key.tun_key; | ||
1304 | |||
1284 | add_nested_action_end(*sfa, start); | 1305 | add_nested_action_end(*sfa, start); |
1285 | 1306 | ||
1286 | return err; | 1307 | return err; |
@@ -1563,17 +1584,20 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb) | |||
1563 | int err; | 1584 | int err; |
1564 | 1585 | ||
1565 | switch (key_type) { | 1586 | switch (key_type) { |
1566 | case OVS_KEY_ATTR_IPV4_TUNNEL: | 1587 | case OVS_KEY_ATTR_TUNNEL_INFO: { |
1588 | struct ovs_tunnel_info *tun_info = nla_data(ovs_key); | ||
1589 | |||
1567 | start = nla_nest_start(skb, OVS_ACTION_ATTR_SET); | 1590 | start = nla_nest_start(skb, OVS_ACTION_ATTR_SET); |
1568 | if (!start) | 1591 | if (!start) |
1569 | return -EMSGSIZE; | 1592 | return -EMSGSIZE; |
1570 | 1593 | ||
1571 | err = ipv4_tun_to_nlattr(skb, nla_data(ovs_key), | 1594 | err = ipv4_tun_to_nlattr(skb, &tun_info->tunnel, |
1572 | nla_data(ovs_key)); | 1595 | nla_data(ovs_key)); |
1573 | if (err) | 1596 | if (err) |
1574 | return err; | 1597 | return err; |
1575 | nla_nest_end(skb, start); | 1598 | nla_nest_end(skb, start); |
1576 | break; | 1599 | break; |
1600 | } | ||
1577 | default: | 1601 | default: |
1578 | if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key)) | 1602 | if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key)) |
1579 | return -EMSGSIZE; | 1603 | return -EMSGSIZE; |