Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: move the ct helper function to nf_conntrack_helper for ovs and tc

Move ovs_ct_helper from openvswitch to nf_conntrack_helper and rename
as nf_ct_helper so that it can be used in TC act_ct in the next patch.
Note that it also adds the checks for the family and proto, as in TC
act_ct, the packets with correct family and proto are not guaranteed.

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Xin Long and committed by
Paolo Abeni
ca71277f 47f3ecf4

+73 -60
+3
include/net/netfilter/nf_conntrack_helper.h
··· 115 115 int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, 116 116 gfp_t flags); 117 117 118 + int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct, 119 + enum ip_conntrack_info ctinfo, u16 proto); 120 + 118 121 void nf_ct_helper_destroy(struct nf_conn *ct); 119 122 120 123 static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+69
net/netfilter/nf_conntrack_helper.c
··· 26 26 #include <net/netfilter/nf_conntrack_extend.h> 27 27 #include <net/netfilter/nf_conntrack_helper.h> 28 28 #include <net/netfilter/nf_conntrack_l4proto.h> 29 + #include <net/netfilter/nf_conntrack_seqadj.h> 29 30 #include <net/netfilter/nf_log.h> 31 + #include <net/ip.h> 30 32 31 33 static DEFINE_MUTEX(nf_ct_helper_mutex); 32 34 struct hlist_head *nf_ct_helper_hash __read_mostly; ··· 241 239 return 0; 242 240 } 243 241 EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper); 242 + 243 + /* 'skb' should already be pulled to nh_ofs. */ 244 + int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct, 245 + enum ip_conntrack_info ctinfo, u16 proto) 246 + { 247 + const struct nf_conntrack_helper *helper; 248 + const struct nf_conn_help *help; 249 + unsigned int protoff; 250 + int err; 251 + 252 + if (ctinfo == IP_CT_RELATED_REPLY) 253 + return NF_ACCEPT; 254 + 255 + help = nfct_help(ct); 256 + if (!help) 257 + return NF_ACCEPT; 258 + 259 + helper = rcu_dereference(help->helper); 260 + if (!helper) 261 + return NF_ACCEPT; 262 + 263 + if (helper->tuple.src.l3num != NFPROTO_UNSPEC && 264 + helper->tuple.src.l3num != proto) 265 + return NF_ACCEPT; 266 + 267 + switch (proto) { 268 + case NFPROTO_IPV4: 269 + protoff = ip_hdrlen(skb); 270 + proto = ip_hdr(skb)->protocol; 271 + break; 272 + case NFPROTO_IPV6: { 273 + u8 nexthdr = ipv6_hdr(skb)->nexthdr; 274 + __be16 frag_off; 275 + int ofs; 276 + 277 + ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 278 + &frag_off); 279 + if (ofs < 0 || (frag_off & htons(~0x7)) != 0) { 280 + pr_debug("proto header not found\n"); 281 + return NF_ACCEPT; 282 + } 283 + protoff = ofs; 284 + proto = nexthdr; 285 + break; 286 + } 287 + default: 288 + WARN_ONCE(1, "helper invoked on non-IP family!"); 289 + return NF_DROP; 290 + } 291 + 292 + if (helper->tuple.dst.protonum != proto) 293 + return NF_ACCEPT; 294 + 295 + err = helper->help(skb, protoff, ct, ctinfo); 296 + if (err != NF_ACCEPT) 297 + return err; 298 + 299 + /* Adjust seqs after helper. This is needed due to some helpers (e.g., 300 + * FTP with NAT) adusting the TCP payload size when mangling IP 301 + * addresses and/or port numbers in the text-based control connection. 302 + */ 303 + if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && 304 + !nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) 305 + return NF_DROP; 306 + return NF_ACCEPT; 307 + } 308 + EXPORT_SYMBOL_GPL(nf_ct_helper); 244 309 245 310 /* appropriate ct lock protecting must be taken by caller */ 246 311 static int unhelp(struct nf_conn *ct, void *me)
+1 -60
net/openvswitch/conntrack.c
··· 434 434 return 0; 435 435 } 436 436 437 - /* 'skb' should already be pulled to nh_ofs. */ 438 - static int ovs_ct_helper(struct sk_buff *skb, u16 proto) 439 - { 440 - const struct nf_conntrack_helper *helper; 441 - const struct nf_conn_help *help; 442 - enum ip_conntrack_info ctinfo; 443 - unsigned int protoff; 444 - struct nf_conn *ct; 445 - int err; 446 - 447 - ct = nf_ct_get(skb, &ctinfo); 448 - if (!ct || ctinfo == IP_CT_RELATED_REPLY) 449 - return NF_ACCEPT; 450 - 451 - help = nfct_help(ct); 452 - if (!help) 453 - return NF_ACCEPT; 454 - 455 - helper = rcu_dereference(help->helper); 456 - if (!helper) 457 - return NF_ACCEPT; 458 - 459 - switch (proto) { 460 - case NFPROTO_IPV4: 461 - protoff = ip_hdrlen(skb); 462 - break; 463 - case NFPROTO_IPV6: { 464 - u8 nexthdr = ipv6_hdr(skb)->nexthdr; 465 - __be16 frag_off; 466 - int ofs; 467 - 468 - ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 469 - &frag_off); 470 - if (ofs < 0 || (frag_off & htons(~0x7)) != 0) { 471 - pr_debug("proto header not found\n"); 472 - return NF_ACCEPT; 473 - } 474 - protoff = ofs; 475 - break; 476 - } 477 - default: 478 - WARN_ONCE(1, "helper invoked on non-IP family!"); 479 - return NF_DROP; 480 - } 481 - 482 - err = helper->help(skb, protoff, ct, ctinfo); 483 - if (err != NF_ACCEPT) 484 - return err; 485 - 486 - /* Adjust seqs after helper. This is needed due to some helpers (e.g., 487 - * FTP with NAT) adusting the TCP payload size when mangling IP 488 - * addresses and/or port numbers in the text-based control connection. 489 - */ 490 - if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && 491 - !nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) 492 - return NF_DROP; 493 - return NF_ACCEPT; 494 - } 495 - 496 437 /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero 497 438 * value if 'skb' is freed. 498 439 */ ··· 979 1038 */ 980 1039 if ((nf_ct_is_confirmed(ct) ? !cached || add_helper : 981 1040 info->commit) && 982 - ovs_ct_helper(skb, info->family) != NF_ACCEPT) { 1041 + nf_ct_helper(skb, ct, ctinfo, info->family) != NF_ACCEPT) { 983 1042 return -EINVAL; 984 1043 } 985 1044