nf_conntrack_bridge.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <linux/types.h>
  3. #include <linux/ip.h>
  4. #include <linux/netfilter.h>
  5. #include <linux/netfilter_ipv6.h>
  6. #include <linux/netfilter_bridge.h>
  7. #include <linux/module.h>
  8. #include <linux/skbuff.h>
  9. #include <linux/icmp.h>
  10. #include <linux/sysctl.h>
  11. #include <net/route.h>
  12. #include <net/ip.h>
  13. #include <net/netfilter/nf_conntrack.h>
  14. #include <net/netfilter/nf_conntrack_core.h>
  15. #include <net/netfilter/nf_conntrack_helper.h>
  16. #include <net/netfilter/nf_conntrack_bridge.h>
  17. #include <linux/netfilter/nf_tables.h>
  18. #include <net/netfilter/nf_tables.h>
  19. #include "../br_private.h"
  20. /* Best effort variant of ip_do_fragment which preserves geometry, unless skbuff
  21. * has been linearized or cloned.
  22. */
  23. static int nf_br_ip_fragment(struct net *net, struct sock *sk,
  24. struct sk_buff *skb,
  25. struct nf_bridge_frag_data *data,
  26. int (*output)(struct net *, struct sock *sk,
  27. const struct nf_bridge_frag_data *data,
  28. struct sk_buff *))
  29. {
  30. int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
  31. unsigned int hlen, ll_rs, mtu;
  32. ktime_t tstamp = skb->tstamp;
  33. struct ip_frag_state state;
  34. struct iphdr *iph;
  35. int err;
  36. /* for offloaded checksums cleanup checksum before fragmentation */
  37. if (skb->ip_summed == CHECKSUM_PARTIAL &&
  38. (err = skb_checksum_help(skb)))
  39. goto blackhole;
  40. iph = ip_hdr(skb);
  41. /*
  42. * Setup starting values
  43. */
  44. hlen = iph->ihl * 4;
  45. frag_max_size -= hlen;
  46. ll_rs = LL_RESERVED_SPACE(skb->dev);
  47. mtu = skb->dev->mtu;
  48. if (skb_has_frag_list(skb)) {
  49. unsigned int first_len = skb_pagelen(skb);
  50. struct ip_fraglist_iter iter;
  51. struct sk_buff *frag;
  52. if (first_len - hlen > mtu ||
  53. skb_headroom(skb) < ll_rs)
  54. goto blackhole;
  55. if (skb_cloned(skb))
  56. goto slow_path;
  57. skb_walk_frags(skb, frag) {
  58. if (frag->len > mtu ||
  59. skb_headroom(frag) < hlen + ll_rs)
  60. goto blackhole;
  61. if (skb_shared(frag))
  62. goto slow_path;
  63. }
  64. ip_fraglist_init(skb, iph, hlen, &iter);
  65. for (;;) {
  66. if (iter.frag)
  67. ip_fraglist_prepare(skb, &iter);
  68. skb->tstamp = tstamp;
  69. err = output(net, sk, data, skb);
  70. if (err || !iter.frag)
  71. break;
  72. skb = ip_fraglist_next(&iter);
  73. }
  74. if (!err)
  75. return 0;
  76. kfree_skb_list(iter.frag);
  77. return err;
  78. }
  79. slow_path:
  80. /* This is a linearized skbuff, the original geometry is lost for us.
  81. * This may also be a clone skbuff, we could preserve the geometry for
  82. * the copies but probably not worth the effort.
  83. */
  84. ip_frag_init(skb, hlen, ll_rs, frag_max_size, false, &state);
  85. while (state.left > 0) {
  86. struct sk_buff *skb2;
  87. skb2 = ip_frag_next(skb, &state);
  88. if (IS_ERR(skb2)) {
  89. err = PTR_ERR(skb2);
  90. goto blackhole;
  91. }
  92. skb2->tstamp = tstamp;
  93. err = output(net, sk, data, skb2);
  94. if (err)
  95. goto blackhole;
  96. }
  97. consume_skb(skb);
  98. return err;
  99. blackhole:
  100. kfree_skb(skb);
  101. return 0;
  102. }
  103. /* ip_defrag() expects IPCB() in place. */
  104. static void br_skb_cb_save(struct sk_buff *skb, struct br_input_skb_cb *cb,
  105. size_t inet_skb_parm_size)
  106. {
  107. memcpy(cb, skb->cb, sizeof(*cb));
  108. memset(skb->cb, 0, inet_skb_parm_size);
  109. }
  110. static void br_skb_cb_restore(struct sk_buff *skb,
  111. const struct br_input_skb_cb *cb,
  112. u16 fragsz)
  113. {
  114. memcpy(skb->cb, cb, sizeof(*cb));
  115. BR_INPUT_SKB_CB(skb)->frag_max_size = fragsz;
  116. }
  117. static unsigned int nf_ct_br_defrag4(struct sk_buff *skb,
  118. const struct nf_hook_state *state)
  119. {
  120. u16 zone_id = NF_CT_DEFAULT_ZONE_ID;
  121. enum ip_conntrack_info ctinfo;
  122. struct br_input_skb_cb cb;
  123. const struct nf_conn *ct;
  124. int err;
  125. if (!ip_is_fragment(ip_hdr(skb)))
  126. return NF_ACCEPT;
  127. ct = nf_ct_get(skb, &ctinfo);
  128. if (ct)
  129. zone_id = nf_ct_zone_id(nf_ct_zone(ct), CTINFO2DIR(ctinfo));
  130. br_skb_cb_save(skb, &cb, sizeof(struct inet_skb_parm));
  131. local_bh_disable();
  132. err = ip_defrag(state->net, skb,
  133. IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
  134. local_bh_enable();
  135. if (!err) {
  136. br_skb_cb_restore(skb, &cb, IPCB(skb)->frag_max_size);
  137. skb->ignore_df = 1;
  138. return NF_ACCEPT;
  139. }
  140. return NF_STOLEN;
  141. }
  142. static unsigned int nf_ct_br_defrag6(struct sk_buff *skb,
  143. const struct nf_hook_state *state)
  144. {
  145. #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
  146. u16 zone_id = NF_CT_DEFAULT_ZONE_ID;
  147. enum ip_conntrack_info ctinfo;
  148. struct br_input_skb_cb cb;
  149. const struct nf_conn *ct;
  150. int err;
  151. ct = nf_ct_get(skb, &ctinfo);
  152. if (ct)
  153. zone_id = nf_ct_zone_id(nf_ct_zone(ct), CTINFO2DIR(ctinfo));
  154. br_skb_cb_save(skb, &cb, sizeof(struct inet6_skb_parm));
  155. err = nf_ct_frag6_gather(state->net, skb,
  156. IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
  157. /* queued */
  158. if (err == -EINPROGRESS)
  159. return NF_STOLEN;
  160. br_skb_cb_restore(skb, &cb, IP6CB(skb)->frag_max_size);
  161. return err == 0 ? NF_ACCEPT : NF_DROP;
  162. #else
  163. return NF_ACCEPT;
  164. #endif
  165. }
  166. static int nf_ct_br_ip_check(const struct sk_buff *skb)
  167. {
  168. const struct iphdr *iph;
  169. int nhoff, len;
  170. nhoff = skb_network_offset(skb);
  171. iph = ip_hdr(skb);
  172. if (iph->ihl < 5 ||
  173. iph->version != 4)
  174. return -1;
  175. len = ntohs(iph->tot_len);
  176. if (skb->len < nhoff + len ||
  177. len < (iph->ihl * 4))
  178. return -1;
  179. return 0;
  180. }
  181. static int nf_ct_br_ipv6_check(const struct sk_buff *skb)
  182. {
  183. const struct ipv6hdr *hdr;
  184. int nhoff, len;
  185. nhoff = skb_network_offset(skb);
  186. hdr = ipv6_hdr(skb);
  187. if (hdr->version != 6)
  188. return -1;
  189. len = ntohs(hdr->payload_len) + sizeof(struct ipv6hdr) + nhoff;
  190. if (skb->len < len)
  191. return -1;
  192. return 0;
  193. }
  194. static unsigned int nf_ct_bridge_pre(void *priv, struct sk_buff *skb,
  195. const struct nf_hook_state *state)
  196. {
  197. struct nf_hook_state bridge_state = *state;
  198. enum ip_conntrack_info ctinfo;
  199. struct nf_conn *ct;
  200. u32 len;
  201. int ret;
  202. ct = nf_ct_get(skb, &ctinfo);
  203. if ((ct && !nf_ct_is_template(ct)) ||
  204. ctinfo == IP_CT_UNTRACKED)
  205. return NF_ACCEPT;
  206. switch (skb->protocol) {
  207. case htons(ETH_P_IP):
  208. if (!pskb_may_pull(skb, sizeof(struct iphdr)))
  209. return NF_ACCEPT;
  210. len = ntohs(ip_hdr(skb)->tot_len);
  211. if (pskb_trim_rcsum(skb, len))
  212. return NF_ACCEPT;
  213. if (nf_ct_br_ip_check(skb))
  214. return NF_ACCEPT;
  215. bridge_state.pf = NFPROTO_IPV4;
  216. ret = nf_ct_br_defrag4(skb, &bridge_state);
  217. break;
  218. case htons(ETH_P_IPV6):
  219. if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
  220. return NF_ACCEPT;
  221. len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len);
  222. if (pskb_trim_rcsum(skb, len))
  223. return NF_ACCEPT;
  224. if (nf_ct_br_ipv6_check(skb))
  225. return NF_ACCEPT;
  226. bridge_state.pf = NFPROTO_IPV6;
  227. ret = nf_ct_br_defrag6(skb, &bridge_state);
  228. break;
  229. default:
  230. nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
  231. return NF_ACCEPT;
  232. }
  233. if (ret != NF_ACCEPT)
  234. return ret;
  235. return nf_conntrack_in(skb, &bridge_state);
  236. }
  237. static void nf_ct_bridge_frag_save(struct sk_buff *skb,
  238. struct nf_bridge_frag_data *data)
  239. {
  240. if (skb_vlan_tag_present(skb)) {
  241. data->vlan_present = true;
  242. data->vlan_tci = skb->vlan_tci;
  243. data->vlan_proto = skb->vlan_proto;
  244. } else {
  245. data->vlan_present = false;
  246. }
  247. skb_copy_from_linear_data_offset(skb, -ETH_HLEN, data->mac, ETH_HLEN);
  248. }
  249. static unsigned int
  250. nf_ct_bridge_refrag(struct sk_buff *skb, const struct nf_hook_state *state,
  251. int (*output)(struct net *, struct sock *sk,
  252. const struct nf_bridge_frag_data *data,
  253. struct sk_buff *))
  254. {
  255. struct nf_bridge_frag_data data;
  256. if (!BR_INPUT_SKB_CB(skb)->frag_max_size)
  257. return NF_ACCEPT;
  258. nf_ct_bridge_frag_save(skb, &data);
  259. switch (skb->protocol) {
  260. case htons(ETH_P_IP):
  261. nf_br_ip_fragment(state->net, state->sk, skb, &data, output);
  262. break;
  263. case htons(ETH_P_IPV6):
  264. nf_br_ip6_fragment(state->net, state->sk, skb, &data, output);
  265. break;
  266. default:
  267. WARN_ON_ONCE(1);
  268. return NF_DROP;
  269. }
  270. return NF_STOLEN;
  271. }
  272. /* Actually only slow path refragmentation needs this. */
  273. static int nf_ct_bridge_frag_restore(struct sk_buff *skb,
  274. const struct nf_bridge_frag_data *data)
  275. {
  276. int err;
  277. err = skb_cow_head(skb, ETH_HLEN);
  278. if (err) {
  279. kfree_skb(skb);
  280. return -ENOMEM;
  281. }
  282. if (data->vlan_present)
  283. __vlan_hwaccel_put_tag(skb, data->vlan_proto, data->vlan_tci);
  284. else if (skb_vlan_tag_present(skb))
  285. __vlan_hwaccel_clear_tag(skb);
  286. skb_copy_to_linear_data_offset(skb, -ETH_HLEN, data->mac, ETH_HLEN);
  287. skb_reset_mac_header(skb);
  288. return 0;
  289. }
  290. static int nf_ct_bridge_refrag_post(struct net *net, struct sock *sk,
  291. const struct nf_bridge_frag_data *data,
  292. struct sk_buff *skb)
  293. {
  294. int err;
  295. err = nf_ct_bridge_frag_restore(skb, data);
  296. if (err < 0)
  297. return err;
  298. return br_dev_queue_push_xmit(net, sk, skb);
  299. }
  300. static unsigned int nf_ct_bridge_confirm(struct sk_buff *skb)
  301. {
  302. enum ip_conntrack_info ctinfo;
  303. struct nf_conn *ct;
  304. int protoff;
  305. ct = nf_ct_get(skb, &ctinfo);
  306. if (!ct || ctinfo == IP_CT_RELATED_REPLY)
  307. return nf_conntrack_confirm(skb);
  308. switch (skb->protocol) {
  309. case htons(ETH_P_IP):
  310. protoff = skb_network_offset(skb) + ip_hdrlen(skb);
  311. break;
  312. case htons(ETH_P_IPV6): {
  313. unsigned char pnum = ipv6_hdr(skb)->nexthdr;
  314. __be16 frag_off;
  315. protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
  316. &frag_off);
  317. if (protoff < 0 || (frag_off & htons(~0x7)) != 0)
  318. return nf_conntrack_confirm(skb);
  319. }
  320. break;
  321. default:
  322. return NF_ACCEPT;
  323. }
  324. return nf_confirm(skb, protoff, ct, ctinfo);
  325. }
  326. static unsigned int nf_ct_bridge_post(void *priv, struct sk_buff *skb,
  327. const struct nf_hook_state *state)
  328. {
  329. int ret;
  330. ret = nf_ct_bridge_confirm(skb);
  331. if (ret != NF_ACCEPT)
  332. return ret;
  333. return nf_ct_bridge_refrag(skb, state, nf_ct_bridge_refrag_post);
  334. }
  335. static struct nf_hook_ops nf_ct_bridge_hook_ops[] __read_mostly = {
  336. {
  337. .hook = nf_ct_bridge_pre,
  338. .pf = NFPROTO_BRIDGE,
  339. .hooknum = NF_BR_PRE_ROUTING,
  340. .priority = NF_IP_PRI_CONNTRACK,
  341. },
  342. {
  343. .hook = nf_ct_bridge_post,
  344. .pf = NFPROTO_BRIDGE,
  345. .hooknum = NF_BR_POST_ROUTING,
  346. .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
  347. },
  348. };
  349. static struct nf_ct_bridge_info bridge_info = {
  350. .ops = nf_ct_bridge_hook_ops,
  351. .ops_size = ARRAY_SIZE(nf_ct_bridge_hook_ops),
  352. .me = THIS_MODULE,
  353. };
  354. static int __init nf_conntrack_l3proto_bridge_init(void)
  355. {
  356. nf_ct_bridge_register(&bridge_info);
  357. return 0;
  358. }
  359. static void __exit nf_conntrack_l3proto_bridge_fini(void)
  360. {
  361. nf_ct_bridge_unregister(&bridge_info);
  362. }
  363. module_init(nf_conntrack_l3proto_bridge_init);
  364. module_exit(nf_conntrack_l3proto_bridge_fini);
  365. MODULE_ALIAS("nf_conntrack-" __stringify(AF_BRIDGE));
  366. MODULE_LICENSE("GPL");