^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * xfrm4_policy.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Kazunori MIYAZAWA @USAGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * YOSHIFUJI Hideaki @USAGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Split up af-specific portion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/l3mdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int tos, int oif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u32 mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct rtable *rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) memset(fl4, 0, sizeof(*fl4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) fl4->daddr = daddr->a4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) fl4->flowi4_tos = tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) fl4->flowi4_mark = mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) fl4->saddr = saddr->a4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) fl4->flowi4_flags = FLOWI_FLAG_SKIP_NH_OIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) rt = __ip_route_output_key(net, fl4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!IS_ERR(rt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return &rt->dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return ERR_CAST(rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const xfrm_address_t *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct flowi4 fl4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int xfrm4_get_saddr(struct net *net, int oif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) xfrm_address_t *saddr, xfrm_address_t *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct flowi4 fl4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr, mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (IS_ERR(dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EHOSTUNREACH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) saddr->a4 = fl4.saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dst_release(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) const struct flowi *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct rtable *rt = (struct rtable *)xdst->route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) const struct flowi4 *fl4 = &fl->u.ip4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) xdst->u.rt.rt_iif = fl4->flowi4_iif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) xdst->u.dst.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Sheit... I remember I did this right. Apparently,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * it was magically lost, so this code needs audit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) xdst->u.rt.rt_is_input = rt->rt_is_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) RTCF_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) xdst->u.rt.rt_type = rt->rt_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) xdst->u.rt.rt_gw_family = rt->rt_gw_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (rt->rt_gw_family == AF_INET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xdst->u.rt.rt_gw4 = rt->rt_gw4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else if (rt->rt_gw_family == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) xdst->u.rt.rt_gw6 = rt->rt_gw6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) xdst->u.rt.rt_pmtu = rt->rt_pmtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rt_add_uncached_list(&xdst->u.rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct sk_buff *skb, u32 mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) bool confirm_neigh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct dst_entry *path = xdst->route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct dst_entry *path = xdst->route;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) path->ops->redirect(path, sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void xfrm4_dst_destroy(struct dst_entry *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dst_destroy_metrics_generic(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (xdst->u.rt.rt_uncached_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) rt_del_uncached_list(&xdst->u.rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) xfrm_dst_destroy(xdst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int unregister)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!unregister)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) xfrm_dst_ifdown(dst, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static struct dst_ops xfrm4_dst_ops_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .family = AF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .update_pmtu = xfrm4_update_pmtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .redirect = xfrm4_redirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .cow_metrics = dst_cow_metrics_generic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .destroy = xfrm4_dst_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .ifdown = xfrm4_dst_ifdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .local_out = __ip_local_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .gc_thresh = 32768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .dst_ops = &xfrm4_dst_ops_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .dst_lookup = xfrm4_dst_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .get_saddr = xfrm4_get_saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .fill_dst = xfrm4_fill_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .blackhole_route = ipv4_blackhole_route,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct ctl_table xfrm4_policy_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .procname = "xfrm4_gc_thresh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .data = &init_net.xfrm.xfrm4_dst_ops.gc_thresh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .proc_handler = proc_dointvec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static __net_init int xfrm4_net_sysctl_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct ctl_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct ctl_table_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) table = xfrm4_policy_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!net_eq(net, &init_net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) hdr = register_net_sysctl(net, "net/ipv4", table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto err_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) net->ipv4.xfrm4_hdr = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) err_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) kfree(table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static __net_exit void xfrm4_net_sysctl_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ctl_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!net->ipv4.xfrm4_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) table = net->ipv4.xfrm4_hdr->ctl_table_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unregister_net_sysctl_table(net->ipv4.xfrm4_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) kfree(table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #else /* CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static inline int xfrm4_net_sysctl_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static inline void xfrm4_net_sysctl_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int __net_init xfrm4_net_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) memcpy(&net->xfrm.xfrm4_dst_ops, &xfrm4_dst_ops_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sizeof(xfrm4_dst_ops_template));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ret = dst_entries_init(&net->xfrm.xfrm4_dst_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = xfrm4_net_sysctl_init(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void __net_exit xfrm4_net_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) xfrm4_net_sysctl_exit(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dst_entries_destroy(&net->xfrm.xfrm4_dst_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static struct pernet_operations __net_initdata xfrm4_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .init = xfrm4_net_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .exit = xfrm4_net_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void __init xfrm4_policy_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) xfrm_policy_register_afinfo(&xfrm4_policy_afinfo, AF_INET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) void __init xfrm4_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) xfrm4_state_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) xfrm4_policy_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) xfrm4_protocol_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) register_pernet_subsys(&xfrm4_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }