diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netlink.c | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 53d98974dcf0..f5bda82c2875 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
| @@ -1100,18 +1100,21 @@ static inline int | |||
| 1100 | ctnetlink_exp_dump_expect(struct sk_buff *skb, | 1100 | ctnetlink_exp_dump_expect(struct sk_buff *skb, |
| 1101 | const struct ip_conntrack_expect *exp) | 1101 | const struct ip_conntrack_expect *exp) |
| 1102 | { | 1102 | { |
| 1103 | struct ip_conntrack *master = exp->master; | ||
| 1103 | u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ); | 1104 | u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ); |
| 1104 | u_int32_t id = htonl(exp->id); | 1105 | u_int32_t id = htonl(exp->id); |
| 1105 | struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT); | ||
| 1106 | 1106 | ||
| 1107 | if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) | 1107 | if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) |
| 1108 | goto nfattr_failure; | 1108 | goto nfattr_failure; |
| 1109 | if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) | 1109 | if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) |
| 1110 | goto nfattr_failure; | 1110 | goto nfattr_failure; |
| 1111 | if (ctnetlink_exp_dump_tuple(skb, | ||
| 1112 | &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | ||
| 1113 | CTA_EXPECT_MASTER) < 0) | ||
| 1114 | goto nfattr_failure; | ||
| 1111 | 1115 | ||
| 1112 | NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); | 1116 | NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); |
| 1113 | NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); | 1117 | NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); |
| 1114 | NFA_NEST_END(skb, nest_parms); | ||
| 1115 | 1118 | ||
| 1116 | return 0; | 1119 | return 0; |
| 1117 | 1120 | ||
| @@ -1259,10 +1262,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1259 | return 0; | 1262 | return 0; |
| 1260 | } | 1263 | } |
| 1261 | 1264 | ||
| 1262 | if (cda[CTA_TUPLE_ORIG-1]) | 1265 | if (cda[CTA_EXPECT_MASTER-1]) |
| 1263 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); | 1266 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER); |
| 1264 | else if (cda[CTA_TUPLE_REPLY-1]) | ||
| 1265 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY); | ||
| 1266 | else | 1267 | else |
| 1267 | return -EINVAL; | 1268 | return -EINVAL; |
| 1268 | 1269 | ||
| @@ -1310,13 +1311,33 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1310 | struct ip_conntrack_helper *h; | 1311 | struct ip_conntrack_helper *h; |
| 1311 | int err; | 1312 | int err; |
| 1312 | 1313 | ||
| 1313 | /* delete by tuple needs either orig or reply tuple */ | 1314 | if (cda[CTA_EXPECT_TUPLE-1]) { |
| 1314 | if (cda[CTA_TUPLE_ORIG-1]) | 1315 | /* delete a single expect by tuple */ |
| 1315 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG); | 1316 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); |
| 1316 | else if (cda[CTA_TUPLE_REPLY-1]) | 1317 | if (err < 0) |
| 1317 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY); | 1318 | return err; |
| 1318 | else if (cda[CTA_HELP_NAME-1]) { | 1319 | |
| 1319 | char *name = NFA_DATA(cda[CTA_HELP_NAME-1]); | 1320 | /* bump usage count to 2 */ |
| 1321 | exp = ip_conntrack_expect_find_get(&tuple); | ||
| 1322 | if (!exp) | ||
| 1323 | return -ENOENT; | ||
| 1324 | |||
| 1325 | if (cda[CTA_EXPECT_ID-1]) { | ||
| 1326 | u_int32_t id = | ||
| 1327 | *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]); | ||
| 1328 | if (exp->id != ntohl(id)) { | ||
| 1329 | ip_conntrack_expect_put(exp); | ||
| 1330 | return -ENOENT; | ||
| 1331 | } | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | /* after list removal, usage count == 1 */ | ||
| 1335 | ip_conntrack_unexpect_related(exp); | ||
| 1336 | /* have to put what we 'get' above. | ||
| 1337 | * after this line usage count == 0 */ | ||
| 1338 | ip_conntrack_expect_put(exp); | ||
| 1339 | } else if (cda[CTA_EXPECT_HELP_NAME-1]) { | ||
| 1340 | char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); | ||
| 1320 | 1341 | ||
| 1321 | /* delete all expectations for this helper */ | 1342 | /* delete all expectations for this helper */ |
| 1322 | write_lock_bh(&ip_conntrack_lock); | 1343 | write_lock_bh(&ip_conntrack_lock); |
| @@ -1332,7 +1353,6 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1332 | __ip_ct_expect_unlink_destroy(exp); | 1353 | __ip_ct_expect_unlink_destroy(exp); |
| 1333 | } | 1354 | } |
| 1334 | write_unlock(&ip_conntrack_lock); | 1355 | write_unlock(&ip_conntrack_lock); |
| 1335 | return 0; | ||
| 1336 | } else { | 1356 | } else { |
| 1337 | /* This basically means we have to flush everything*/ | 1357 | /* This basically means we have to flush everything*/ |
| 1338 | write_lock_bh(&ip_conntrack_lock); | 1358 | write_lock_bh(&ip_conntrack_lock); |
| @@ -1342,30 +1362,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1342 | __ip_ct_expect_unlink_destroy(exp); | 1362 | __ip_ct_expect_unlink_destroy(exp); |
| 1343 | } | 1363 | } |
| 1344 | write_unlock_bh(&ip_conntrack_lock); | 1364 | write_unlock_bh(&ip_conntrack_lock); |
| 1345 | return 0; | ||
| 1346 | } | 1365 | } |
| 1347 | 1366 | ||
| 1348 | if (err < 0) | ||
| 1349 | return err; | ||
| 1350 | |||
| 1351 | /* bump usage count to 2 */ | ||
| 1352 | exp = ip_conntrack_expect_find_get(&tuple); | ||
| 1353 | if (!exp) | ||
| 1354 | return -ENOENT; | ||
| 1355 | |||
| 1356 | if (cda[CTA_EXPECT_ID-1]) { | ||
| 1357 | u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]); | ||
| 1358 | if (exp->id != ntohl(id)) { | ||
| 1359 | ip_conntrack_expect_put(exp); | ||
| 1360 | return -ENOENT; | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | /* after list removal, usage count == 1 */ | ||
| 1365 | ip_conntrack_unexpect_related(exp); | ||
| 1366 | /* have to put what we 'get' above. after this line usage count == 0 */ | ||
| 1367 | ip_conntrack_expect_put(exp); | ||
| 1368 | |||
| 1369 | return 0; | 1367 | return 0; |
| 1370 | } | 1368 | } |
| 1371 | static int | 1369 | static int |
| @@ -1385,21 +1383,14 @@ ctnetlink_create_expect(struct nfattr *cda[]) | |||
| 1385 | 1383 | ||
| 1386 | DEBUGP("entered %s\n", __FUNCTION__); | 1384 | DEBUGP("entered %s\n", __FUNCTION__); |
| 1387 | 1385 | ||
| 1386 | /* caller guarantees that those three CTA_EXPECT_* exist */ | ||
| 1388 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); | 1387 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); |
| 1389 | if (err < 0) | 1388 | if (err < 0) |
| 1390 | return err; | 1389 | return err; |
| 1391 | err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK); | 1390 | err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK); |
| 1392 | if (err < 0) | 1391 | if (err < 0) |
| 1393 | return err; | 1392 | return err; |
| 1394 | 1393 | err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER); | |
| 1395 | if (cda[CTA_TUPLE_ORIG-1]) | ||
| 1396 | err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_TUPLE_ORIG); | ||
| 1397 | else if (cda[CTA_TUPLE_REPLY-1]) | ||
| 1398 | err = ctnetlink_parse_tuple(cda, &master_tuple, | ||
| 1399 | CTA_TUPLE_REPLY); | ||
| 1400 | else | ||
| 1401 | return -EINVAL; | ||
| 1402 | |||
| 1403 | if (err < 0) | 1394 | if (err < 0) |
| 1404 | return err; | 1395 | return err; |
| 1405 | 1396 | ||
| @@ -1444,7 +1435,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1444 | 1435 | ||
| 1445 | DEBUGP("entered %s\n", __FUNCTION__); | 1436 | DEBUGP("entered %s\n", __FUNCTION__); |
| 1446 | 1437 | ||
| 1447 | if (!cda[CTA_EXPECT_TUPLE-1] || !cda[CTA_EXPECT_MASK-1]) | 1438 | if (!cda[CTA_EXPECT_TUPLE-1] |
| 1439 | || !cda[CTA_EXPECT_MASK-1] | ||
| 1440 | || !cda[CTA_EXPECT_MASTER-1]) | ||
| 1448 | return -EINVAL; | 1441 | return -EINVAL; |
| 1449 | 1442 | ||
| 1450 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); | 1443 | err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE); |
