aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r--net/openvswitch/flow_netlink.c38
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
1151static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, int len) 1151static 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
1170static 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;