* drivers/net/amt.c:2752 amt_rcv() error: we previously assumed 'amt' could be null (see line 2680)
@ 2022-06-02 16:16 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2022-06-02 16:16 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 35374 bytes --]
CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
CC: linux-kernel(a)vger.kernel.org
TO: Taehee Yoo <ap420073@gmail.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: d1dc87763f406d4e67caf16dbe438a5647692395
commit: b9022b53adad88fd6cf2b9718c9e498504f3e1dd amt: add control plane of amt interface
date: 7 months ago
:::::: branch date: 15 hours ago
:::::: commit date: 7 months ago
config: x86_64-rhel-8.3-kselftests (https://download.01.org/0day-ci/archive/20220603/202206030020.XGD7PFRU-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.3.0-1) 11.3.0
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
drivers/net/amt.c:2752 amt_rcv() error: we previously assumed 'amt' could be null (see line 2680)
vim +/amt +2752 drivers/net/amt.c
b9022b53adad88 Taehee Yoo 2021-10-31 1 // SPDX-License-Identifier: GPL-2.0-or-later
b9022b53adad88 Taehee Yoo 2021-10-31 2 /* Copyright (c) 2021 Taehee Yoo <ap420073@gmail.com> */
b9022b53adad88 Taehee Yoo 2021-10-31 3
b9022b53adad88 Taehee Yoo 2021-10-31 4 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
b9022b53adad88 Taehee Yoo 2021-10-31 5
b9022b53adad88 Taehee Yoo 2021-10-31 6 #include <linux/module.h>
b9022b53adad88 Taehee Yoo 2021-10-31 7 #include <linux/skbuff.h>
b9022b53adad88 Taehee Yoo 2021-10-31 8 #include <linux/udp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 9 #include <linux/jhash.h>
b9022b53adad88 Taehee Yoo 2021-10-31 10 #include <linux/if_tunnel.h>
b9022b53adad88 Taehee Yoo 2021-10-31 11 #include <linux/net.h>
b9022b53adad88 Taehee Yoo 2021-10-31 12 #include <linux/igmp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 13 #include <linux/workqueue.h>
b9022b53adad88 Taehee Yoo 2021-10-31 14 #include <net/net_namespace.h>
b9022b53adad88 Taehee Yoo 2021-10-31 15 #include <net/protocol.h>
b9022b53adad88 Taehee Yoo 2021-10-31 16 #include <net/ip.h>
b9022b53adad88 Taehee Yoo 2021-10-31 17 #include <net/udp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 18 #include <net/udp_tunnel.h>
b9022b53adad88 Taehee Yoo 2021-10-31 19 #include <net/icmp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 20 #include <net/mld.h>
b9022b53adad88 Taehee Yoo 2021-10-31 21 #include <net/amt.h>
b9022b53adad88 Taehee Yoo 2021-10-31 22 #include <uapi/linux/amt.h>
b9022b53adad88 Taehee Yoo 2021-10-31 23 #include <linux/security.h>
b9022b53adad88 Taehee Yoo 2021-10-31 24 #include <net/gro_cells.h>
b9022b53adad88 Taehee Yoo 2021-10-31 25 #include <net/ipv6.h>
b9022b53adad88 Taehee Yoo 2021-10-31 26 #include <net/protocol.h>
b9022b53adad88 Taehee Yoo 2021-10-31 27 #include <net/if_inet6.h>
b9022b53adad88 Taehee Yoo 2021-10-31 28 #include <net/ndisc.h>
b9022b53adad88 Taehee Yoo 2021-10-31 29 #include <net/addrconf.h>
b9022b53adad88 Taehee Yoo 2021-10-31 30 #include <net/ip6_route.h>
b9022b53adad88 Taehee Yoo 2021-10-31 31 #include <net/inet_common.h>
b9022b53adad88 Taehee Yoo 2021-10-31 32
b9022b53adad88 Taehee Yoo 2021-10-31 33 static struct workqueue_struct *amt_wq;
b9022b53adad88 Taehee Yoo 2021-10-31 34
b9022b53adad88 Taehee Yoo 2021-10-31 35 static struct socket *amt_create_sock(struct net *net, __be16 port)
b9022b53adad88 Taehee Yoo 2021-10-31 36 {
b9022b53adad88 Taehee Yoo 2021-10-31 37 struct udp_port_cfg udp_conf;
b9022b53adad88 Taehee Yoo 2021-10-31 38 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 39 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 40
b9022b53adad88 Taehee Yoo 2021-10-31 41 memset(&udp_conf, 0, sizeof(udp_conf));
b9022b53adad88 Taehee Yoo 2021-10-31 42 udp_conf.family = AF_INET;
b9022b53adad88 Taehee Yoo 2021-10-31 43 udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
b9022b53adad88 Taehee Yoo 2021-10-31 44
b9022b53adad88 Taehee Yoo 2021-10-31 45 udp_conf.local_udp_port = port;
b9022b53adad88 Taehee Yoo 2021-10-31 46
b9022b53adad88 Taehee Yoo 2021-10-31 47 err = udp_sock_create(net, &udp_conf, &sock);
b9022b53adad88 Taehee Yoo 2021-10-31 48 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 49 return ERR_PTR(err);
b9022b53adad88 Taehee Yoo 2021-10-31 50
b9022b53adad88 Taehee Yoo 2021-10-31 51 return sock;
b9022b53adad88 Taehee Yoo 2021-10-31 52 }
b9022b53adad88 Taehee Yoo 2021-10-31 53
b9022b53adad88 Taehee Yoo 2021-10-31 54 static int amt_socket_create(struct amt_dev *amt)
b9022b53adad88 Taehee Yoo 2021-10-31 55 {
b9022b53adad88 Taehee Yoo 2021-10-31 56 struct udp_tunnel_sock_cfg tunnel_cfg;
b9022b53adad88 Taehee Yoo 2021-10-31 57 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 58
b9022b53adad88 Taehee Yoo 2021-10-31 59 sock = amt_create_sock(amt->net, amt->relay_port);
b9022b53adad88 Taehee Yoo 2021-10-31 60 if (IS_ERR(sock))
b9022b53adad88 Taehee Yoo 2021-10-31 61 return PTR_ERR(sock);
b9022b53adad88 Taehee Yoo 2021-10-31 62
b9022b53adad88 Taehee Yoo 2021-10-31 63 /* Mark socket as an encapsulation socket */
b9022b53adad88 Taehee Yoo 2021-10-31 64 memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
b9022b53adad88 Taehee Yoo 2021-10-31 65 tunnel_cfg.sk_user_data = amt;
b9022b53adad88 Taehee Yoo 2021-10-31 66 tunnel_cfg.encap_type = 1;
b9022b53adad88 Taehee Yoo 2021-10-31 67 tunnel_cfg.encap_destroy = NULL;
b9022b53adad88 Taehee Yoo 2021-10-31 68 setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg);
b9022b53adad88 Taehee Yoo 2021-10-31 69
b9022b53adad88 Taehee Yoo 2021-10-31 70 rcu_assign_pointer(amt->sock, sock);
b9022b53adad88 Taehee Yoo 2021-10-31 71 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 72 }
b9022b53adad88 Taehee Yoo 2021-10-31 73
b9022b53adad88 Taehee Yoo 2021-10-31 74 static int amt_dev_open(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 75 {
b9022b53adad88 Taehee Yoo 2021-10-31 76 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 77 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 78
b9022b53adad88 Taehee Yoo 2021-10-31 79 amt->ready4 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 80 amt->ready6 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 81
b9022b53adad88 Taehee Yoo 2021-10-31 82 err = amt_socket_create(amt);
b9022b53adad88 Taehee Yoo 2021-10-31 83 if (err)
b9022b53adad88 Taehee Yoo 2021-10-31 84 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 85
b9022b53adad88 Taehee Yoo 2021-10-31 86 amt->req_cnt = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 87 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 88 get_random_bytes(&amt->key, sizeof(siphash_key_t));
b9022b53adad88 Taehee Yoo 2021-10-31 89
b9022b53adad88 Taehee Yoo 2021-10-31 90 amt->status = AMT_STATUS_INIT;
b9022b53adad88 Taehee Yoo 2021-10-31 91 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 92 }
b9022b53adad88 Taehee Yoo 2021-10-31 93
b9022b53adad88 Taehee Yoo 2021-10-31 94 static int amt_dev_stop(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 95 {
b9022b53adad88 Taehee Yoo 2021-10-31 96 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 97 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 98
b9022b53adad88 Taehee Yoo 2021-10-31 99 /* shutdown */
b9022b53adad88 Taehee Yoo 2021-10-31 100 sock = rtnl_dereference(amt->sock);
b9022b53adad88 Taehee Yoo 2021-10-31 101 RCU_INIT_POINTER(amt->sock, NULL);
b9022b53adad88 Taehee Yoo 2021-10-31 102 synchronize_net();
b9022b53adad88 Taehee Yoo 2021-10-31 103 if (sock)
b9022b53adad88 Taehee Yoo 2021-10-31 104 udp_tunnel_sock_release(sock);
b9022b53adad88 Taehee Yoo 2021-10-31 105
b9022b53adad88 Taehee Yoo 2021-10-31 106 amt->ready4 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 107 amt->ready6 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 108 amt->req_cnt = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 109 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 110
b9022b53adad88 Taehee Yoo 2021-10-31 111 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 112 }
b9022b53adad88 Taehee Yoo 2021-10-31 113
b9022b53adad88 Taehee Yoo 2021-10-31 114 static const struct device_type amt_type = {
b9022b53adad88 Taehee Yoo 2021-10-31 115 .name = "amt",
b9022b53adad88 Taehee Yoo 2021-10-31 116 };
b9022b53adad88 Taehee Yoo 2021-10-31 117
b9022b53adad88 Taehee Yoo 2021-10-31 118 static int amt_dev_init(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 119 {
b9022b53adad88 Taehee Yoo 2021-10-31 120 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 121 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 122
b9022b53adad88 Taehee Yoo 2021-10-31 123 amt->dev = dev;
b9022b53adad88 Taehee Yoo 2021-10-31 124 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
b9022b53adad88 Taehee Yoo 2021-10-31 125 if (!dev->tstats)
b9022b53adad88 Taehee Yoo 2021-10-31 126 return -ENOMEM;
b9022b53adad88 Taehee Yoo 2021-10-31 127
b9022b53adad88 Taehee Yoo 2021-10-31 128 err = gro_cells_init(&amt->gro_cells, dev);
b9022b53adad88 Taehee Yoo 2021-10-31 129 if (err) {
b9022b53adad88 Taehee Yoo 2021-10-31 130 free_percpu(dev->tstats);
b9022b53adad88 Taehee Yoo 2021-10-31 131 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 132 }
b9022b53adad88 Taehee Yoo 2021-10-31 133
b9022b53adad88 Taehee Yoo 2021-10-31 134 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 135 }
b9022b53adad88 Taehee Yoo 2021-10-31 136
b9022b53adad88 Taehee Yoo 2021-10-31 137 static void amt_dev_uninit(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 138 {
b9022b53adad88 Taehee Yoo 2021-10-31 139 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 140
b9022b53adad88 Taehee Yoo 2021-10-31 141 gro_cells_destroy(&amt->gro_cells);
b9022b53adad88 Taehee Yoo 2021-10-31 142 free_percpu(dev->tstats);
b9022b53adad88 Taehee Yoo 2021-10-31 143 }
b9022b53adad88 Taehee Yoo 2021-10-31 144
b9022b53adad88 Taehee Yoo 2021-10-31 145 static const struct net_device_ops amt_netdev_ops = {
b9022b53adad88 Taehee Yoo 2021-10-31 146 .ndo_init = amt_dev_init,
b9022b53adad88 Taehee Yoo 2021-10-31 147 .ndo_uninit = amt_dev_uninit,
b9022b53adad88 Taehee Yoo 2021-10-31 148 .ndo_open = amt_dev_open,
b9022b53adad88 Taehee Yoo 2021-10-31 149 .ndo_stop = amt_dev_stop,
b9022b53adad88 Taehee Yoo 2021-10-31 150 .ndo_get_stats64 = dev_get_tstats64,
b9022b53adad88 Taehee Yoo 2021-10-31 151 };
b9022b53adad88 Taehee Yoo 2021-10-31 152
b9022b53adad88 Taehee Yoo 2021-10-31 153 static void amt_link_setup(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 154 {
b9022b53adad88 Taehee Yoo 2021-10-31 155 dev->netdev_ops = &amt_netdev_ops;
b9022b53adad88 Taehee Yoo 2021-10-31 156 dev->needs_free_netdev = true;
b9022b53adad88 Taehee Yoo 2021-10-31 157 SET_NETDEV_DEVTYPE(dev, &amt_type);
b9022b53adad88 Taehee Yoo 2021-10-31 158 dev->min_mtu = ETH_MIN_MTU;
b9022b53adad88 Taehee Yoo 2021-10-31 159 dev->max_mtu = ETH_MAX_MTU;
b9022b53adad88 Taehee Yoo 2021-10-31 160 dev->type = ARPHRD_NONE;
b9022b53adad88 Taehee Yoo 2021-10-31 161 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
b9022b53adad88 Taehee Yoo 2021-10-31 162 dev->hard_header_len = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 163 dev->addr_len = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 164 dev->priv_flags |= IFF_NO_QUEUE;
b9022b53adad88 Taehee Yoo 2021-10-31 165 dev->features |= NETIF_F_LLTX;
b9022b53adad88 Taehee Yoo 2021-10-31 166 dev->features |= NETIF_F_GSO_SOFTWARE;
b9022b53adad88 Taehee Yoo 2021-10-31 167 dev->features |= NETIF_F_NETNS_LOCAL;
b9022b53adad88 Taehee Yoo 2021-10-31 168 dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
b9022b53adad88 Taehee Yoo 2021-10-31 169 dev->hw_features |= NETIF_F_FRAGLIST | NETIF_F_RXCSUM;
b9022b53adad88 Taehee Yoo 2021-10-31 170 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
b9022b53adad88 Taehee Yoo 2021-10-31 171 eth_hw_addr_random(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 172 eth_zero_addr(dev->broadcast);
b9022b53adad88 Taehee Yoo 2021-10-31 173 ether_setup(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 174 }
b9022b53adad88 Taehee Yoo 2021-10-31 175
b9022b53adad88 Taehee Yoo 2021-10-31 176 static const struct nla_policy amt_policy[IFLA_AMT_MAX + 1] = {
b9022b53adad88 Taehee Yoo 2021-10-31 177 [IFLA_AMT_MODE] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 178 [IFLA_AMT_RELAY_PORT] = { .type = NLA_U16 },
b9022b53adad88 Taehee Yoo 2021-10-31 179 [IFLA_AMT_GATEWAY_PORT] = { .type = NLA_U16 },
b9022b53adad88 Taehee Yoo 2021-10-31 180 [IFLA_AMT_LINK] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 181 [IFLA_AMT_LOCAL_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 182 [IFLA_AMT_REMOTE_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 183 [IFLA_AMT_DISCOVERY_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 184 [IFLA_AMT_MAX_TUNNELS] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 185 };
b9022b53adad88 Taehee Yoo 2021-10-31 186
b9022b53adad88 Taehee Yoo 2021-10-31 187 static int amt_validate(struct nlattr *tb[], struct nlattr *data[],
b9022b53adad88 Taehee Yoo 2021-10-31 188 struct netlink_ext_ack *extack)
b9022b53adad88 Taehee Yoo 2021-10-31 189 {
b9022b53adad88 Taehee Yoo 2021-10-31 190 if (!data)
b9022b53adad88 Taehee Yoo 2021-10-31 191 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 192
b9022b53adad88 Taehee Yoo 2021-10-31 193 if (!data[IFLA_AMT_LINK]) {
b9022b53adad88 Taehee Yoo 2021-10-31 194 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 195 "Link attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 196 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 197 }
b9022b53adad88 Taehee Yoo 2021-10-31 198
b9022b53adad88 Taehee Yoo 2021-10-31 199 if (!data[IFLA_AMT_MODE]) {
b9022b53adad88 Taehee Yoo 2021-10-31 200 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_MODE],
b9022b53adad88 Taehee Yoo 2021-10-31 201 "Mode attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 202 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 203 }
b9022b53adad88 Taehee Yoo 2021-10-31 204
b9022b53adad88 Taehee Yoo 2021-10-31 205 if (nla_get_u32(data[IFLA_AMT_MODE]) > AMT_MODE_MAX) {
b9022b53adad88 Taehee Yoo 2021-10-31 206 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_MODE],
b9022b53adad88 Taehee Yoo 2021-10-31 207 "Mode attribute is not valid");
b9022b53adad88 Taehee Yoo 2021-10-31 208 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 209 }
b9022b53adad88 Taehee Yoo 2021-10-31 210
b9022b53adad88 Taehee Yoo 2021-10-31 211 if (!data[IFLA_AMT_LOCAL_IP]) {
b9022b53adad88 Taehee Yoo 2021-10-31 212 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 213 "Local attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 214 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 215 }
b9022b53adad88 Taehee Yoo 2021-10-31 216
b9022b53adad88 Taehee Yoo 2021-10-31 217 if (!data[IFLA_AMT_DISCOVERY_IP] &&
b9022b53adad88 Taehee Yoo 2021-10-31 218 nla_get_u32(data[IFLA_AMT_MODE]) == AMT_MODE_GATEWAY) {
b9022b53adad88 Taehee Yoo 2021-10-31 219 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_LOCAL_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 220 "Discovery attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 221 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 222 }
b9022b53adad88 Taehee Yoo 2021-10-31 223
b9022b53adad88 Taehee Yoo 2021-10-31 224 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 225 }
b9022b53adad88 Taehee Yoo 2021-10-31 226
b9022b53adad88 Taehee Yoo 2021-10-31 227 static int amt_newlink(struct net *net, struct net_device *dev,
b9022b53adad88 Taehee Yoo 2021-10-31 228 struct nlattr *tb[], struct nlattr *data[],
b9022b53adad88 Taehee Yoo 2021-10-31 229 struct netlink_ext_ack *extack)
b9022b53adad88 Taehee Yoo 2021-10-31 230 {
b9022b53adad88 Taehee Yoo 2021-10-31 231 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 232 int err = -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 233
b9022b53adad88 Taehee Yoo 2021-10-31 234 amt->net = net;
b9022b53adad88 Taehee Yoo 2021-10-31 235 amt->mode = nla_get_u32(data[IFLA_AMT_MODE]);
b9022b53adad88 Taehee Yoo 2021-10-31 236
b9022b53adad88 Taehee Yoo 2021-10-31 237 if (data[IFLA_AMT_MAX_TUNNELS])
b9022b53adad88 Taehee Yoo 2021-10-31 238 amt->max_tunnels = nla_get_u32(data[IFLA_AMT_MAX_TUNNELS]);
b9022b53adad88 Taehee Yoo 2021-10-31 239 else
b9022b53adad88 Taehee Yoo 2021-10-31 240 amt->max_tunnels = AMT_MAX_TUNNELS;
b9022b53adad88 Taehee Yoo 2021-10-31 241
b9022b53adad88 Taehee Yoo 2021-10-31 242 spin_lock_init(&amt->lock);
b9022b53adad88 Taehee Yoo 2021-10-31 243 amt->max_groups = AMT_MAX_GROUP;
b9022b53adad88 Taehee Yoo 2021-10-31 244 amt->max_sources = AMT_MAX_SOURCE;
b9022b53adad88 Taehee Yoo 2021-10-31 245 amt->hash_buckets = AMT_HSIZE;
b9022b53adad88 Taehee Yoo 2021-10-31 246 amt->nr_tunnels = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 247 get_random_bytes(&amt->hash_seed, sizeof(amt->hash_seed));
b9022b53adad88 Taehee Yoo 2021-10-31 248 amt->stream_dev = dev_get_by_index(net,
b9022b53adad88 Taehee Yoo 2021-10-31 249 nla_get_u32(data[IFLA_AMT_LINK]));
b9022b53adad88 Taehee Yoo 2021-10-31 250 if (!amt->stream_dev) {
b9022b53adad88 Taehee Yoo 2021-10-31 251 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 252 "Can't find stream device");
b9022b53adad88 Taehee Yoo 2021-10-31 253 return -ENODEV;
b9022b53adad88 Taehee Yoo 2021-10-31 254 }
b9022b53adad88 Taehee Yoo 2021-10-31 255
b9022b53adad88 Taehee Yoo 2021-10-31 256 if (amt->stream_dev->type != ARPHRD_ETHER) {
b9022b53adad88 Taehee Yoo 2021-10-31 257 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 258 "Invalid stream device type");
b9022b53adad88 Taehee Yoo 2021-10-31 259 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 260 }
b9022b53adad88 Taehee Yoo 2021-10-31 261
b9022b53adad88 Taehee Yoo 2021-10-31 262 amt->local_ip = nla_get_in_addr(data[IFLA_AMT_LOCAL_IP]);
b9022b53adad88 Taehee Yoo 2021-10-31 263 if (ipv4_is_loopback(amt->local_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 264 ipv4_is_zeronet(amt->local_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 265 ipv4_is_multicast(amt->local_ip)) {
b9022b53adad88 Taehee Yoo 2021-10-31 266 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LOCAL_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 267 "Invalid Local address");
b9022b53adad88 Taehee Yoo 2021-10-31 268 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 269 }
b9022b53adad88 Taehee Yoo 2021-10-31 270
b9022b53adad88 Taehee Yoo 2021-10-31 271 if (data[IFLA_AMT_RELAY_PORT])
b9022b53adad88 Taehee Yoo 2021-10-31 272 amt->relay_port = nla_get_be16(data[IFLA_AMT_RELAY_PORT]);
b9022b53adad88 Taehee Yoo 2021-10-31 273 else
b9022b53adad88 Taehee Yoo 2021-10-31 274 amt->relay_port = htons(IANA_AMT_UDP_PORT);
b9022b53adad88 Taehee Yoo 2021-10-31 275
b9022b53adad88 Taehee Yoo 2021-10-31 276 if (data[IFLA_AMT_GATEWAY_PORT])
b9022b53adad88 Taehee Yoo 2021-10-31 277 amt->gw_port = nla_get_be16(data[IFLA_AMT_GATEWAY_PORT]);
b9022b53adad88 Taehee Yoo 2021-10-31 278 else
b9022b53adad88 Taehee Yoo 2021-10-31 279 amt->gw_port = htons(IANA_AMT_UDP_PORT);
b9022b53adad88 Taehee Yoo 2021-10-31 280
b9022b53adad88 Taehee Yoo 2021-10-31 281 if (!amt->relay_port) {
b9022b53adad88 Taehee Yoo 2021-10-31 282 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 283 "relay port must not be 0");
b9022b53adad88 Taehee Yoo 2021-10-31 284 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 285 }
b9022b53adad88 Taehee Yoo 2021-10-31 286 if (amt->mode == AMT_MODE_RELAY) {
b9022b53adad88 Taehee Yoo 2021-10-31 287 amt->qrv = amt->net->ipv4.sysctl_igmp_qrv;
b9022b53adad88 Taehee Yoo 2021-10-31 288 amt->qri = 10;
b9022b53adad88 Taehee Yoo 2021-10-31 289 dev->needed_headroom = amt->stream_dev->needed_headroom +
b9022b53adad88 Taehee Yoo 2021-10-31 290 AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 291 dev->mtu = amt->stream_dev->mtu - AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 292 dev->max_mtu = dev->mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 293 dev->min_mtu = ETH_MIN_MTU + AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 294 } else {
b9022b53adad88 Taehee Yoo 2021-10-31 295 if (!data[IFLA_AMT_DISCOVERY_IP]) {
b9022b53adad88 Taehee Yoo 2021-10-31 296 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 297 "discovery must be set in gateway mode");
b9022b53adad88 Taehee Yoo 2021-10-31 298 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 299 }
b9022b53adad88 Taehee Yoo 2021-10-31 300 if (!amt->gw_port) {
b9022b53adad88 Taehee Yoo 2021-10-31 301 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 302 "gateway port must not be 0");
b9022b53adad88 Taehee Yoo 2021-10-31 303 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 304 }
b9022b53adad88 Taehee Yoo 2021-10-31 305 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 306 amt->discovery_ip = nla_get_in_addr(data[IFLA_AMT_DISCOVERY_IP]);
b9022b53adad88 Taehee Yoo 2021-10-31 307 if (ipv4_is_loopback(amt->discovery_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 308 ipv4_is_zeronet(amt->discovery_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 309 ipv4_is_multicast(amt->discovery_ip)) {
b9022b53adad88 Taehee Yoo 2021-10-31 310 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 311 "discovery must be unicast");
b9022b53adad88 Taehee Yoo 2021-10-31 312 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 313 }
b9022b53adad88 Taehee Yoo 2021-10-31 314
b9022b53adad88 Taehee Yoo 2021-10-31 315 dev->needed_headroom = amt->stream_dev->needed_headroom +
b9022b53adad88 Taehee Yoo 2021-10-31 316 AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 317 dev->mtu = amt->stream_dev->mtu - AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 318 dev->max_mtu = dev->mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 319 dev->min_mtu = ETH_MIN_MTU + AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 320 }
b9022b53adad88 Taehee Yoo 2021-10-31 321 amt->qi = AMT_INIT_QUERY_INTERVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 322
b9022b53adad88 Taehee Yoo 2021-10-31 323 err = register_netdevice(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 324 if (err < 0) {
b9022b53adad88 Taehee Yoo 2021-10-31 325 netdev_dbg(dev, "failed to register new netdev %d\n", err);
b9022b53adad88 Taehee Yoo 2021-10-31 326 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 327 }
b9022b53adad88 Taehee Yoo 2021-10-31 328
b9022b53adad88 Taehee Yoo 2021-10-31 329 err = netdev_upper_dev_link(amt->stream_dev, dev, extack);
b9022b53adad88 Taehee Yoo 2021-10-31 330 if (err < 0) {
b9022b53adad88 Taehee Yoo 2021-10-31 331 unregister_netdevice(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 332 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 333 }
b9022b53adad88 Taehee Yoo 2021-10-31 334
b9022b53adad88 Taehee Yoo 2021-10-31 335 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 336 err:
b9022b53adad88 Taehee Yoo 2021-10-31 337 dev_put(amt->stream_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 338 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 339 }
b9022b53adad88 Taehee Yoo 2021-10-31 340
b9022b53adad88 Taehee Yoo 2021-10-31 341 static void amt_dellink(struct net_device *dev, struct list_head *head)
b9022b53adad88 Taehee Yoo 2021-10-31 342 {
b9022b53adad88 Taehee Yoo 2021-10-31 343 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 344
b9022b53adad88 Taehee Yoo 2021-10-31 345 unregister_netdevice_queue(dev, head);
b9022b53adad88 Taehee Yoo 2021-10-31 346 netdev_upper_dev_unlink(amt->stream_dev, dev);
b9022b53adad88 Taehee Yoo 2021-10-31 347 dev_put(amt->stream_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 348 }
b9022b53adad88 Taehee Yoo 2021-10-31 349
b9022b53adad88 Taehee Yoo 2021-10-31 350 static size_t amt_get_size(const struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 351 {
b9022b53adad88 Taehee Yoo 2021-10-31 352 return nla_total_size(sizeof(__u32)) + /* IFLA_AMT_MODE */
b9022b53adad88 Taehee Yoo 2021-10-31 353 nla_total_size(sizeof(__u16)) + /* IFLA_AMT_RELAY_PORT */
b9022b53adad88 Taehee Yoo 2021-10-31 354 nla_total_size(sizeof(__u16)) + /* IFLA_AMT_GATEWAY_PORT */
b9022b53adad88 Taehee Yoo 2021-10-31 355 nla_total_size(sizeof(__u32)) + /* IFLA_AMT_LINK */
b9022b53adad88 Taehee Yoo 2021-10-31 356 nla_total_size(sizeof(__u32)) + /* IFLA_MAX_TUNNELS */
b9022b53adad88 Taehee Yoo 2021-10-31 357 nla_total_size(sizeof(struct iphdr)) + /* IFLA_AMT_DISCOVERY_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 358 nla_total_size(sizeof(struct iphdr)) + /* IFLA_AMT_REMOTE_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 359 nla_total_size(sizeof(struct iphdr)); /* IFLA_AMT_LOCAL_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 360 }
b9022b53adad88 Taehee Yoo 2021-10-31 361
b9022b53adad88 Taehee Yoo 2021-10-31 362 static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 363 {
b9022b53adad88 Taehee Yoo 2021-10-31 364 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 365
b9022b53adad88 Taehee Yoo 2021-10-31 366 if (nla_put_u32(skb, IFLA_AMT_MODE, amt->mode))
b9022b53adad88 Taehee Yoo 2021-10-31 367 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 368 if (nla_put_be16(skb, IFLA_AMT_RELAY_PORT, amt->relay_port))
b9022b53adad88 Taehee Yoo 2021-10-31 369 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 370 if (nla_put_be16(skb, IFLA_AMT_GATEWAY_PORT, amt->gw_port))
b9022b53adad88 Taehee Yoo 2021-10-31 371 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 372 if (nla_put_u32(skb, IFLA_AMT_LINK, amt->stream_dev->ifindex))
b9022b53adad88 Taehee Yoo 2021-10-31 373 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 374 if (nla_put_in_addr(skb, IFLA_AMT_LOCAL_IP, amt->local_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 375 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 376 if (nla_put_in_addr(skb, IFLA_AMT_DISCOVERY_IP, amt->discovery_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 377 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 378 if (amt->remote_ip)
b9022b53adad88 Taehee Yoo 2021-10-31 379 if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, amt->remote_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 380 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 381 if (nla_put_u32(skb, IFLA_AMT_MAX_TUNNELS, amt->max_tunnels))
b9022b53adad88 Taehee Yoo 2021-10-31 382 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 383
b9022b53adad88 Taehee Yoo 2021-10-31 384 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 385
b9022b53adad88 Taehee Yoo 2021-10-31 386 nla_put_failure:
b9022b53adad88 Taehee Yoo 2021-10-31 387 return -EMSGSIZE;
b9022b53adad88 Taehee Yoo 2021-10-31 388 }
b9022b53adad88 Taehee Yoo 2021-10-31 389
b9022b53adad88 Taehee Yoo 2021-10-31 390 static struct rtnl_link_ops amt_link_ops __read_mostly = {
b9022b53adad88 Taehee Yoo 2021-10-31 391 .kind = "amt",
b9022b53adad88 Taehee Yoo 2021-10-31 392 .maxtype = IFLA_AMT_MAX,
b9022b53adad88 Taehee Yoo 2021-10-31 393 .policy = amt_policy,
b9022b53adad88 Taehee Yoo 2021-10-31 394 .priv_size = sizeof(struct amt_dev),
b9022b53adad88 Taehee Yoo 2021-10-31 395 .setup = amt_link_setup,
b9022b53adad88 Taehee Yoo 2021-10-31 396 .validate = amt_validate,
b9022b53adad88 Taehee Yoo 2021-10-31 397 .newlink = amt_newlink,
b9022b53adad88 Taehee Yoo 2021-10-31 398 .dellink = amt_dellink,
b9022b53adad88 Taehee Yoo 2021-10-31 399 .get_size = amt_get_size,
b9022b53adad88 Taehee Yoo 2021-10-31 400 .fill_info = amt_fill_info,
b9022b53adad88 Taehee Yoo 2021-10-31 401 };
b9022b53adad88 Taehee Yoo 2021-10-31 402
b9022b53adad88 Taehee Yoo 2021-10-31 403 static struct net_device *amt_lookup_upper_dev(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 404 {
b9022b53adad88 Taehee Yoo 2021-10-31 405 struct net_device *upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 406 struct amt_dev *amt;
b9022b53adad88 Taehee Yoo 2021-10-31 407
b9022b53adad88 Taehee Yoo 2021-10-31 408 for_each_netdev(dev_net(dev), upper_dev) {
b9022b53adad88 Taehee Yoo 2021-10-31 409 if (netif_is_amt(upper_dev)) {
b9022b53adad88 Taehee Yoo 2021-10-31 410 amt = netdev_priv(upper_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 411 if (amt->stream_dev == dev)
b9022b53adad88 Taehee Yoo 2021-10-31 412 return upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 413 }
b9022b53adad88 Taehee Yoo 2021-10-31 414 }
b9022b53adad88 Taehee Yoo 2021-10-31 415
b9022b53adad88 Taehee Yoo 2021-10-31 416 return NULL;
b9022b53adad88 Taehee Yoo 2021-10-31 417 }
b9022b53adad88 Taehee Yoo 2021-10-31 418
b9022b53adad88 Taehee Yoo 2021-10-31 419 static int amt_device_event(struct notifier_block *unused,
b9022b53adad88 Taehee Yoo 2021-10-31 420 unsigned long event, void *ptr)
b9022b53adad88 Taehee Yoo 2021-10-31 421 {
b9022b53adad88 Taehee Yoo 2021-10-31 422 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
b9022b53adad88 Taehee Yoo 2021-10-31 423 struct net_device *upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 424 struct amt_dev *amt;
b9022b53adad88 Taehee Yoo 2021-10-31 425 LIST_HEAD(list);
b9022b53adad88 Taehee Yoo 2021-10-31 426 int new_mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 427
b9022b53adad88 Taehee Yoo 2021-10-31 428 upper_dev = amt_lookup_upper_dev(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 429 if (!upper_dev)
b9022b53adad88 Taehee Yoo 2021-10-31 430 return NOTIFY_DONE;
b9022b53adad88 Taehee Yoo 2021-10-31 431 amt = netdev_priv(upper_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 432
b9022b53adad88 Taehee Yoo 2021-10-31 433 switch (event) {
b9022b53adad88 Taehee Yoo 2021-10-31 434 case NETDEV_UNREGISTER:
b9022b53adad88 Taehee Yoo 2021-10-31 435 amt_dellink(amt->dev, &list);
b9022b53adad88 Taehee Yoo 2021-10-31 436 unregister_netdevice_many(&list);
b9022b53adad88 Taehee Yoo 2021-10-31 437 break;
b9022b53adad88 Taehee Yoo 2021-10-31 438 case NETDEV_CHANGEMTU:
b9022b53adad88 Taehee Yoo 2021-10-31 439 if (amt->mode == AMT_MODE_RELAY)
b9022b53adad88 Taehee Yoo 2021-10-31 440 new_mtu = dev->mtu - AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 441 else
b9022b53adad88 Taehee Yoo 2021-10-31 442 new_mtu = dev->mtu - AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 443
b9022b53adad88 Taehee Yoo 2021-10-31 444 dev_set_mtu(amt->dev, new_mtu);
b9022b53adad88 Taehee Yoo 2021-10-31 445 break;
b9022b53adad88 Taehee Yoo 2021-10-31 446 }
b9022b53adad88 Taehee Yoo 2021-10-31 447
b9022b53adad88 Taehee Yoo 2021-10-31 448 return NOTIFY_DONE;
b9022b53adad88 Taehee Yoo 2021-10-31 449 }
b9022b53adad88 Taehee Yoo 2021-10-31 450
b9022b53adad88 Taehee Yoo 2021-10-31 451 static struct notifier_block amt_notifier_block __read_mostly = {
b9022b53adad88 Taehee Yoo 2021-10-31 452 .notifier_call = amt_device_event,
b9022b53adad88 Taehee Yoo 2021-10-31 453 };
b9022b53adad88 Taehee Yoo 2021-10-31 454
b9022b53adad88 Taehee Yoo 2021-10-31 455 static int __init amt_init(void)
b9022b53adad88 Taehee Yoo 2021-10-31 456 {
b9022b53adad88 Taehee Yoo 2021-10-31 457 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 458
b9022b53adad88 Taehee Yoo 2021-10-31 459 err = register_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 460 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 461 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 462
b9022b53adad88 Taehee Yoo 2021-10-31 463 err = rtnl_link_register(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 464 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 465 goto unregister_notifier;
b9022b53adad88 Taehee Yoo 2021-10-31 466
b9022b53adad88 Taehee Yoo 2021-10-31 467 amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 1);
b9022b53adad88 Taehee Yoo 2021-10-31 468 if (!amt_wq)
b9022b53adad88 Taehee Yoo 2021-10-31 469 goto rtnl_unregister;
b9022b53adad88 Taehee Yoo 2021-10-31 470
b9022b53adad88 Taehee Yoo 2021-10-31 471 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 472
b9022b53adad88 Taehee Yoo 2021-10-31 473 rtnl_unregister:
b9022b53adad88 Taehee Yoo 2021-10-31 474 rtnl_link_unregister(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 475 unregister_notifier:
b9022b53adad88 Taehee Yoo 2021-10-31 476 unregister_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 477 err:
b9022b53adad88 Taehee Yoo 2021-10-31 478 pr_err("error loading AMT module loaded\n");
b9022b53adad88 Taehee Yoo 2021-10-31 479 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 480 }
b9022b53adad88 Taehee Yoo 2021-10-31 481 late_initcall(amt_init);
b9022b53adad88 Taehee Yoo 2021-10-31 482
b9022b53adad88 Taehee Yoo 2021-10-31 483 static void __exit amt_fini(void)
b9022b53adad88 Taehee Yoo 2021-10-31 484 {
b9022b53adad88 Taehee Yoo 2021-10-31 485 rtnl_link_unregister(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 486 unregister_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 487 destroy_workqueue(amt_wq);
b9022b53adad88 Taehee Yoo 2021-10-31 488 }
b9022b53adad88 Taehee Yoo 2021-10-31 489 module_exit(amt_fini);
b9022b53adad88 Taehee Yoo 2021-10-31 490
b9022b53adad88 Taehee Yoo 2021-10-31 491 MODULE_LICENSE("GPL");
b9022b53adad88 Taehee Yoo 2021-10-31 492 MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
b9022b53adad88 Taehee Yoo 2021-10-31 493 MODULE_ALIAS_RTNL_LINK("amt");
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 2+ messages in thread
* drivers/net/amt.c:2752 amt_rcv() error: we previously assumed 'amt' could be null (see line 2680)
@ 2022-06-03 3:02 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2022-06-03 3:02 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 35374 bytes --]
CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
CC: linux-kernel(a)vger.kernel.org
TO: Taehee Yoo <ap420073@gmail.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: d1dc87763f406d4e67caf16dbe438a5647692395
commit: b9022b53adad88fd6cf2b9718c9e498504f3e1dd amt: add control plane of amt interface
date: 7 months ago
:::::: branch date: 25 hours ago
:::::: commit date: 7 months ago
config: x86_64-rhel-8.3-kselftests (https://download.01.org/0day-ci/archive/20220603/202206031058.IDwO5ped-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.3.0-1) 11.3.0
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
drivers/net/amt.c:2752 amt_rcv() error: we previously assumed 'amt' could be null (see line 2680)
vim +/amt +2752 drivers/net/amt.c
b9022b53adad88 Taehee Yoo 2021-10-31 1 // SPDX-License-Identifier: GPL-2.0-or-later
b9022b53adad88 Taehee Yoo 2021-10-31 2 /* Copyright (c) 2021 Taehee Yoo <ap420073@gmail.com> */
b9022b53adad88 Taehee Yoo 2021-10-31 3
b9022b53adad88 Taehee Yoo 2021-10-31 4 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
b9022b53adad88 Taehee Yoo 2021-10-31 5
b9022b53adad88 Taehee Yoo 2021-10-31 6 #include <linux/module.h>
b9022b53adad88 Taehee Yoo 2021-10-31 7 #include <linux/skbuff.h>
b9022b53adad88 Taehee Yoo 2021-10-31 8 #include <linux/udp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 9 #include <linux/jhash.h>
b9022b53adad88 Taehee Yoo 2021-10-31 10 #include <linux/if_tunnel.h>
b9022b53adad88 Taehee Yoo 2021-10-31 11 #include <linux/net.h>
b9022b53adad88 Taehee Yoo 2021-10-31 12 #include <linux/igmp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 13 #include <linux/workqueue.h>
b9022b53adad88 Taehee Yoo 2021-10-31 14 #include <net/net_namespace.h>
b9022b53adad88 Taehee Yoo 2021-10-31 15 #include <net/protocol.h>
b9022b53adad88 Taehee Yoo 2021-10-31 16 #include <net/ip.h>
b9022b53adad88 Taehee Yoo 2021-10-31 17 #include <net/udp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 18 #include <net/udp_tunnel.h>
b9022b53adad88 Taehee Yoo 2021-10-31 19 #include <net/icmp.h>
b9022b53adad88 Taehee Yoo 2021-10-31 20 #include <net/mld.h>
b9022b53adad88 Taehee Yoo 2021-10-31 21 #include <net/amt.h>
b9022b53adad88 Taehee Yoo 2021-10-31 22 #include <uapi/linux/amt.h>
b9022b53adad88 Taehee Yoo 2021-10-31 23 #include <linux/security.h>
b9022b53adad88 Taehee Yoo 2021-10-31 24 #include <net/gro_cells.h>
b9022b53adad88 Taehee Yoo 2021-10-31 25 #include <net/ipv6.h>
b9022b53adad88 Taehee Yoo 2021-10-31 26 #include <net/protocol.h>
b9022b53adad88 Taehee Yoo 2021-10-31 27 #include <net/if_inet6.h>
b9022b53adad88 Taehee Yoo 2021-10-31 28 #include <net/ndisc.h>
b9022b53adad88 Taehee Yoo 2021-10-31 29 #include <net/addrconf.h>
b9022b53adad88 Taehee Yoo 2021-10-31 30 #include <net/ip6_route.h>
b9022b53adad88 Taehee Yoo 2021-10-31 31 #include <net/inet_common.h>
b9022b53adad88 Taehee Yoo 2021-10-31 32
b9022b53adad88 Taehee Yoo 2021-10-31 33 static struct workqueue_struct *amt_wq;
b9022b53adad88 Taehee Yoo 2021-10-31 34
b9022b53adad88 Taehee Yoo 2021-10-31 35 static struct socket *amt_create_sock(struct net *net, __be16 port)
b9022b53adad88 Taehee Yoo 2021-10-31 36 {
b9022b53adad88 Taehee Yoo 2021-10-31 37 struct udp_port_cfg udp_conf;
b9022b53adad88 Taehee Yoo 2021-10-31 38 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 39 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 40
b9022b53adad88 Taehee Yoo 2021-10-31 41 memset(&udp_conf, 0, sizeof(udp_conf));
b9022b53adad88 Taehee Yoo 2021-10-31 42 udp_conf.family = AF_INET;
b9022b53adad88 Taehee Yoo 2021-10-31 43 udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
b9022b53adad88 Taehee Yoo 2021-10-31 44
b9022b53adad88 Taehee Yoo 2021-10-31 45 udp_conf.local_udp_port = port;
b9022b53adad88 Taehee Yoo 2021-10-31 46
b9022b53adad88 Taehee Yoo 2021-10-31 47 err = udp_sock_create(net, &udp_conf, &sock);
b9022b53adad88 Taehee Yoo 2021-10-31 48 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 49 return ERR_PTR(err);
b9022b53adad88 Taehee Yoo 2021-10-31 50
b9022b53adad88 Taehee Yoo 2021-10-31 51 return sock;
b9022b53adad88 Taehee Yoo 2021-10-31 52 }
b9022b53adad88 Taehee Yoo 2021-10-31 53
b9022b53adad88 Taehee Yoo 2021-10-31 54 static int amt_socket_create(struct amt_dev *amt)
b9022b53adad88 Taehee Yoo 2021-10-31 55 {
b9022b53adad88 Taehee Yoo 2021-10-31 56 struct udp_tunnel_sock_cfg tunnel_cfg;
b9022b53adad88 Taehee Yoo 2021-10-31 57 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 58
b9022b53adad88 Taehee Yoo 2021-10-31 59 sock = amt_create_sock(amt->net, amt->relay_port);
b9022b53adad88 Taehee Yoo 2021-10-31 60 if (IS_ERR(sock))
b9022b53adad88 Taehee Yoo 2021-10-31 61 return PTR_ERR(sock);
b9022b53adad88 Taehee Yoo 2021-10-31 62
b9022b53adad88 Taehee Yoo 2021-10-31 63 /* Mark socket as an encapsulation socket */
b9022b53adad88 Taehee Yoo 2021-10-31 64 memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
b9022b53adad88 Taehee Yoo 2021-10-31 65 tunnel_cfg.sk_user_data = amt;
b9022b53adad88 Taehee Yoo 2021-10-31 66 tunnel_cfg.encap_type = 1;
b9022b53adad88 Taehee Yoo 2021-10-31 67 tunnel_cfg.encap_destroy = NULL;
b9022b53adad88 Taehee Yoo 2021-10-31 68 setup_udp_tunnel_sock(amt->net, sock, &tunnel_cfg);
b9022b53adad88 Taehee Yoo 2021-10-31 69
b9022b53adad88 Taehee Yoo 2021-10-31 70 rcu_assign_pointer(amt->sock, sock);
b9022b53adad88 Taehee Yoo 2021-10-31 71 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 72 }
b9022b53adad88 Taehee Yoo 2021-10-31 73
b9022b53adad88 Taehee Yoo 2021-10-31 74 static int amt_dev_open(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 75 {
b9022b53adad88 Taehee Yoo 2021-10-31 76 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 77 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 78
b9022b53adad88 Taehee Yoo 2021-10-31 79 amt->ready4 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 80 amt->ready6 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 81
b9022b53adad88 Taehee Yoo 2021-10-31 82 err = amt_socket_create(amt);
b9022b53adad88 Taehee Yoo 2021-10-31 83 if (err)
b9022b53adad88 Taehee Yoo 2021-10-31 84 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 85
b9022b53adad88 Taehee Yoo 2021-10-31 86 amt->req_cnt = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 87 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 88 get_random_bytes(&amt->key, sizeof(siphash_key_t));
b9022b53adad88 Taehee Yoo 2021-10-31 89
b9022b53adad88 Taehee Yoo 2021-10-31 90 amt->status = AMT_STATUS_INIT;
b9022b53adad88 Taehee Yoo 2021-10-31 91 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 92 }
b9022b53adad88 Taehee Yoo 2021-10-31 93
b9022b53adad88 Taehee Yoo 2021-10-31 94 static int amt_dev_stop(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 95 {
b9022b53adad88 Taehee Yoo 2021-10-31 96 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 97 struct socket *sock;
b9022b53adad88 Taehee Yoo 2021-10-31 98
b9022b53adad88 Taehee Yoo 2021-10-31 99 /* shutdown */
b9022b53adad88 Taehee Yoo 2021-10-31 100 sock = rtnl_dereference(amt->sock);
b9022b53adad88 Taehee Yoo 2021-10-31 101 RCU_INIT_POINTER(amt->sock, NULL);
b9022b53adad88 Taehee Yoo 2021-10-31 102 synchronize_net();
b9022b53adad88 Taehee Yoo 2021-10-31 103 if (sock)
b9022b53adad88 Taehee Yoo 2021-10-31 104 udp_tunnel_sock_release(sock);
b9022b53adad88 Taehee Yoo 2021-10-31 105
b9022b53adad88 Taehee Yoo 2021-10-31 106 amt->ready4 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 107 amt->ready6 = false;
b9022b53adad88 Taehee Yoo 2021-10-31 108 amt->req_cnt = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 109 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 110
b9022b53adad88 Taehee Yoo 2021-10-31 111 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 112 }
b9022b53adad88 Taehee Yoo 2021-10-31 113
b9022b53adad88 Taehee Yoo 2021-10-31 114 static const struct device_type amt_type = {
b9022b53adad88 Taehee Yoo 2021-10-31 115 .name = "amt",
b9022b53adad88 Taehee Yoo 2021-10-31 116 };
b9022b53adad88 Taehee Yoo 2021-10-31 117
b9022b53adad88 Taehee Yoo 2021-10-31 118 static int amt_dev_init(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 119 {
b9022b53adad88 Taehee Yoo 2021-10-31 120 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 121 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 122
b9022b53adad88 Taehee Yoo 2021-10-31 123 amt->dev = dev;
b9022b53adad88 Taehee Yoo 2021-10-31 124 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
b9022b53adad88 Taehee Yoo 2021-10-31 125 if (!dev->tstats)
b9022b53adad88 Taehee Yoo 2021-10-31 126 return -ENOMEM;
b9022b53adad88 Taehee Yoo 2021-10-31 127
b9022b53adad88 Taehee Yoo 2021-10-31 128 err = gro_cells_init(&amt->gro_cells, dev);
b9022b53adad88 Taehee Yoo 2021-10-31 129 if (err) {
b9022b53adad88 Taehee Yoo 2021-10-31 130 free_percpu(dev->tstats);
b9022b53adad88 Taehee Yoo 2021-10-31 131 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 132 }
b9022b53adad88 Taehee Yoo 2021-10-31 133
b9022b53adad88 Taehee Yoo 2021-10-31 134 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 135 }
b9022b53adad88 Taehee Yoo 2021-10-31 136
b9022b53adad88 Taehee Yoo 2021-10-31 137 static void amt_dev_uninit(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 138 {
b9022b53adad88 Taehee Yoo 2021-10-31 139 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 140
b9022b53adad88 Taehee Yoo 2021-10-31 141 gro_cells_destroy(&amt->gro_cells);
b9022b53adad88 Taehee Yoo 2021-10-31 142 free_percpu(dev->tstats);
b9022b53adad88 Taehee Yoo 2021-10-31 143 }
b9022b53adad88 Taehee Yoo 2021-10-31 144
b9022b53adad88 Taehee Yoo 2021-10-31 145 static const struct net_device_ops amt_netdev_ops = {
b9022b53adad88 Taehee Yoo 2021-10-31 146 .ndo_init = amt_dev_init,
b9022b53adad88 Taehee Yoo 2021-10-31 147 .ndo_uninit = amt_dev_uninit,
b9022b53adad88 Taehee Yoo 2021-10-31 148 .ndo_open = amt_dev_open,
b9022b53adad88 Taehee Yoo 2021-10-31 149 .ndo_stop = amt_dev_stop,
b9022b53adad88 Taehee Yoo 2021-10-31 150 .ndo_get_stats64 = dev_get_tstats64,
b9022b53adad88 Taehee Yoo 2021-10-31 151 };
b9022b53adad88 Taehee Yoo 2021-10-31 152
b9022b53adad88 Taehee Yoo 2021-10-31 153 static void amt_link_setup(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 154 {
b9022b53adad88 Taehee Yoo 2021-10-31 155 dev->netdev_ops = &amt_netdev_ops;
b9022b53adad88 Taehee Yoo 2021-10-31 156 dev->needs_free_netdev = true;
b9022b53adad88 Taehee Yoo 2021-10-31 157 SET_NETDEV_DEVTYPE(dev, &amt_type);
b9022b53adad88 Taehee Yoo 2021-10-31 158 dev->min_mtu = ETH_MIN_MTU;
b9022b53adad88 Taehee Yoo 2021-10-31 159 dev->max_mtu = ETH_MAX_MTU;
b9022b53adad88 Taehee Yoo 2021-10-31 160 dev->type = ARPHRD_NONE;
b9022b53adad88 Taehee Yoo 2021-10-31 161 dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
b9022b53adad88 Taehee Yoo 2021-10-31 162 dev->hard_header_len = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 163 dev->addr_len = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 164 dev->priv_flags |= IFF_NO_QUEUE;
b9022b53adad88 Taehee Yoo 2021-10-31 165 dev->features |= NETIF_F_LLTX;
b9022b53adad88 Taehee Yoo 2021-10-31 166 dev->features |= NETIF_F_GSO_SOFTWARE;
b9022b53adad88 Taehee Yoo 2021-10-31 167 dev->features |= NETIF_F_NETNS_LOCAL;
b9022b53adad88 Taehee Yoo 2021-10-31 168 dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
b9022b53adad88 Taehee Yoo 2021-10-31 169 dev->hw_features |= NETIF_F_FRAGLIST | NETIF_F_RXCSUM;
b9022b53adad88 Taehee Yoo 2021-10-31 170 dev->hw_features |= NETIF_F_GSO_SOFTWARE;
b9022b53adad88 Taehee Yoo 2021-10-31 171 eth_hw_addr_random(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 172 eth_zero_addr(dev->broadcast);
b9022b53adad88 Taehee Yoo 2021-10-31 173 ether_setup(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 174 }
b9022b53adad88 Taehee Yoo 2021-10-31 175
b9022b53adad88 Taehee Yoo 2021-10-31 176 static const struct nla_policy amt_policy[IFLA_AMT_MAX + 1] = {
b9022b53adad88 Taehee Yoo 2021-10-31 177 [IFLA_AMT_MODE] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 178 [IFLA_AMT_RELAY_PORT] = { .type = NLA_U16 },
b9022b53adad88 Taehee Yoo 2021-10-31 179 [IFLA_AMT_GATEWAY_PORT] = { .type = NLA_U16 },
b9022b53adad88 Taehee Yoo 2021-10-31 180 [IFLA_AMT_LINK] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 181 [IFLA_AMT_LOCAL_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 182 [IFLA_AMT_REMOTE_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 183 [IFLA_AMT_DISCOVERY_IP] = { .len = sizeof_field(struct iphdr, daddr) },
b9022b53adad88 Taehee Yoo 2021-10-31 184 [IFLA_AMT_MAX_TUNNELS] = { .type = NLA_U32 },
b9022b53adad88 Taehee Yoo 2021-10-31 185 };
b9022b53adad88 Taehee Yoo 2021-10-31 186
b9022b53adad88 Taehee Yoo 2021-10-31 187 static int amt_validate(struct nlattr *tb[], struct nlattr *data[],
b9022b53adad88 Taehee Yoo 2021-10-31 188 struct netlink_ext_ack *extack)
b9022b53adad88 Taehee Yoo 2021-10-31 189 {
b9022b53adad88 Taehee Yoo 2021-10-31 190 if (!data)
b9022b53adad88 Taehee Yoo 2021-10-31 191 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 192
b9022b53adad88 Taehee Yoo 2021-10-31 193 if (!data[IFLA_AMT_LINK]) {
b9022b53adad88 Taehee Yoo 2021-10-31 194 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 195 "Link attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 196 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 197 }
b9022b53adad88 Taehee Yoo 2021-10-31 198
b9022b53adad88 Taehee Yoo 2021-10-31 199 if (!data[IFLA_AMT_MODE]) {
b9022b53adad88 Taehee Yoo 2021-10-31 200 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_MODE],
b9022b53adad88 Taehee Yoo 2021-10-31 201 "Mode attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 202 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 203 }
b9022b53adad88 Taehee Yoo 2021-10-31 204
b9022b53adad88 Taehee Yoo 2021-10-31 205 if (nla_get_u32(data[IFLA_AMT_MODE]) > AMT_MODE_MAX) {
b9022b53adad88 Taehee Yoo 2021-10-31 206 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_MODE],
b9022b53adad88 Taehee Yoo 2021-10-31 207 "Mode attribute is not valid");
b9022b53adad88 Taehee Yoo 2021-10-31 208 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 209 }
b9022b53adad88 Taehee Yoo 2021-10-31 210
b9022b53adad88 Taehee Yoo 2021-10-31 211 if (!data[IFLA_AMT_LOCAL_IP]) {
b9022b53adad88 Taehee Yoo 2021-10-31 212 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 213 "Local attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 214 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 215 }
b9022b53adad88 Taehee Yoo 2021-10-31 216
b9022b53adad88 Taehee Yoo 2021-10-31 217 if (!data[IFLA_AMT_DISCOVERY_IP] &&
b9022b53adad88 Taehee Yoo 2021-10-31 218 nla_get_u32(data[IFLA_AMT_MODE]) == AMT_MODE_GATEWAY) {
b9022b53adad88 Taehee Yoo 2021-10-31 219 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_AMT_LOCAL_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 220 "Discovery attribute is required");
b9022b53adad88 Taehee Yoo 2021-10-31 221 return -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 222 }
b9022b53adad88 Taehee Yoo 2021-10-31 223
b9022b53adad88 Taehee Yoo 2021-10-31 224 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 225 }
b9022b53adad88 Taehee Yoo 2021-10-31 226
b9022b53adad88 Taehee Yoo 2021-10-31 227 static int amt_newlink(struct net *net, struct net_device *dev,
b9022b53adad88 Taehee Yoo 2021-10-31 228 struct nlattr *tb[], struct nlattr *data[],
b9022b53adad88 Taehee Yoo 2021-10-31 229 struct netlink_ext_ack *extack)
b9022b53adad88 Taehee Yoo 2021-10-31 230 {
b9022b53adad88 Taehee Yoo 2021-10-31 231 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 232 int err = -EINVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 233
b9022b53adad88 Taehee Yoo 2021-10-31 234 amt->net = net;
b9022b53adad88 Taehee Yoo 2021-10-31 235 amt->mode = nla_get_u32(data[IFLA_AMT_MODE]);
b9022b53adad88 Taehee Yoo 2021-10-31 236
b9022b53adad88 Taehee Yoo 2021-10-31 237 if (data[IFLA_AMT_MAX_TUNNELS])
b9022b53adad88 Taehee Yoo 2021-10-31 238 amt->max_tunnels = nla_get_u32(data[IFLA_AMT_MAX_TUNNELS]);
b9022b53adad88 Taehee Yoo 2021-10-31 239 else
b9022b53adad88 Taehee Yoo 2021-10-31 240 amt->max_tunnels = AMT_MAX_TUNNELS;
b9022b53adad88 Taehee Yoo 2021-10-31 241
b9022b53adad88 Taehee Yoo 2021-10-31 242 spin_lock_init(&amt->lock);
b9022b53adad88 Taehee Yoo 2021-10-31 243 amt->max_groups = AMT_MAX_GROUP;
b9022b53adad88 Taehee Yoo 2021-10-31 244 amt->max_sources = AMT_MAX_SOURCE;
b9022b53adad88 Taehee Yoo 2021-10-31 245 amt->hash_buckets = AMT_HSIZE;
b9022b53adad88 Taehee Yoo 2021-10-31 246 amt->nr_tunnels = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 247 get_random_bytes(&amt->hash_seed, sizeof(amt->hash_seed));
b9022b53adad88 Taehee Yoo 2021-10-31 248 amt->stream_dev = dev_get_by_index(net,
b9022b53adad88 Taehee Yoo 2021-10-31 249 nla_get_u32(data[IFLA_AMT_LINK]));
b9022b53adad88 Taehee Yoo 2021-10-31 250 if (!amt->stream_dev) {
b9022b53adad88 Taehee Yoo 2021-10-31 251 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 252 "Can't find stream device");
b9022b53adad88 Taehee Yoo 2021-10-31 253 return -ENODEV;
b9022b53adad88 Taehee Yoo 2021-10-31 254 }
b9022b53adad88 Taehee Yoo 2021-10-31 255
b9022b53adad88 Taehee Yoo 2021-10-31 256 if (amt->stream_dev->type != ARPHRD_ETHER) {
b9022b53adad88 Taehee Yoo 2021-10-31 257 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LINK],
b9022b53adad88 Taehee Yoo 2021-10-31 258 "Invalid stream device type");
b9022b53adad88 Taehee Yoo 2021-10-31 259 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 260 }
b9022b53adad88 Taehee Yoo 2021-10-31 261
b9022b53adad88 Taehee Yoo 2021-10-31 262 amt->local_ip = nla_get_in_addr(data[IFLA_AMT_LOCAL_IP]);
b9022b53adad88 Taehee Yoo 2021-10-31 263 if (ipv4_is_loopback(amt->local_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 264 ipv4_is_zeronet(amt->local_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 265 ipv4_is_multicast(amt->local_ip)) {
b9022b53adad88 Taehee Yoo 2021-10-31 266 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_LOCAL_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 267 "Invalid Local address");
b9022b53adad88 Taehee Yoo 2021-10-31 268 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 269 }
b9022b53adad88 Taehee Yoo 2021-10-31 270
b9022b53adad88 Taehee Yoo 2021-10-31 271 if (data[IFLA_AMT_RELAY_PORT])
b9022b53adad88 Taehee Yoo 2021-10-31 272 amt->relay_port = nla_get_be16(data[IFLA_AMT_RELAY_PORT]);
b9022b53adad88 Taehee Yoo 2021-10-31 273 else
b9022b53adad88 Taehee Yoo 2021-10-31 274 amt->relay_port = htons(IANA_AMT_UDP_PORT);
b9022b53adad88 Taehee Yoo 2021-10-31 275
b9022b53adad88 Taehee Yoo 2021-10-31 276 if (data[IFLA_AMT_GATEWAY_PORT])
b9022b53adad88 Taehee Yoo 2021-10-31 277 amt->gw_port = nla_get_be16(data[IFLA_AMT_GATEWAY_PORT]);
b9022b53adad88 Taehee Yoo 2021-10-31 278 else
b9022b53adad88 Taehee Yoo 2021-10-31 279 amt->gw_port = htons(IANA_AMT_UDP_PORT);
b9022b53adad88 Taehee Yoo 2021-10-31 280
b9022b53adad88 Taehee Yoo 2021-10-31 281 if (!amt->relay_port) {
b9022b53adad88 Taehee Yoo 2021-10-31 282 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 283 "relay port must not be 0");
b9022b53adad88 Taehee Yoo 2021-10-31 284 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 285 }
b9022b53adad88 Taehee Yoo 2021-10-31 286 if (amt->mode == AMT_MODE_RELAY) {
b9022b53adad88 Taehee Yoo 2021-10-31 287 amt->qrv = amt->net->ipv4.sysctl_igmp_qrv;
b9022b53adad88 Taehee Yoo 2021-10-31 288 amt->qri = 10;
b9022b53adad88 Taehee Yoo 2021-10-31 289 dev->needed_headroom = amt->stream_dev->needed_headroom +
b9022b53adad88 Taehee Yoo 2021-10-31 290 AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 291 dev->mtu = amt->stream_dev->mtu - AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 292 dev->max_mtu = dev->mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 293 dev->min_mtu = ETH_MIN_MTU + AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 294 } else {
b9022b53adad88 Taehee Yoo 2021-10-31 295 if (!data[IFLA_AMT_DISCOVERY_IP]) {
b9022b53adad88 Taehee Yoo 2021-10-31 296 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 297 "discovery must be set in gateway mode");
b9022b53adad88 Taehee Yoo 2021-10-31 298 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 299 }
b9022b53adad88 Taehee Yoo 2021-10-31 300 if (!amt->gw_port) {
b9022b53adad88 Taehee Yoo 2021-10-31 301 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 302 "gateway port must not be 0");
b9022b53adad88 Taehee Yoo 2021-10-31 303 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 304 }
b9022b53adad88 Taehee Yoo 2021-10-31 305 amt->remote_ip = 0;
b9022b53adad88 Taehee Yoo 2021-10-31 306 amt->discovery_ip = nla_get_in_addr(data[IFLA_AMT_DISCOVERY_IP]);
b9022b53adad88 Taehee Yoo 2021-10-31 307 if (ipv4_is_loopback(amt->discovery_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 308 ipv4_is_zeronet(amt->discovery_ip) ||
b9022b53adad88 Taehee Yoo 2021-10-31 309 ipv4_is_multicast(amt->discovery_ip)) {
b9022b53adad88 Taehee Yoo 2021-10-31 310 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
b9022b53adad88 Taehee Yoo 2021-10-31 311 "discovery must be unicast");
b9022b53adad88 Taehee Yoo 2021-10-31 312 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 313 }
b9022b53adad88 Taehee Yoo 2021-10-31 314
b9022b53adad88 Taehee Yoo 2021-10-31 315 dev->needed_headroom = amt->stream_dev->needed_headroom +
b9022b53adad88 Taehee Yoo 2021-10-31 316 AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 317 dev->mtu = amt->stream_dev->mtu - AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 318 dev->max_mtu = dev->mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 319 dev->min_mtu = ETH_MIN_MTU + AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 320 }
b9022b53adad88 Taehee Yoo 2021-10-31 321 amt->qi = AMT_INIT_QUERY_INTERVAL;
b9022b53adad88 Taehee Yoo 2021-10-31 322
b9022b53adad88 Taehee Yoo 2021-10-31 323 err = register_netdevice(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 324 if (err < 0) {
b9022b53adad88 Taehee Yoo 2021-10-31 325 netdev_dbg(dev, "failed to register new netdev %d\n", err);
b9022b53adad88 Taehee Yoo 2021-10-31 326 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 327 }
b9022b53adad88 Taehee Yoo 2021-10-31 328
b9022b53adad88 Taehee Yoo 2021-10-31 329 err = netdev_upper_dev_link(amt->stream_dev, dev, extack);
b9022b53adad88 Taehee Yoo 2021-10-31 330 if (err < 0) {
b9022b53adad88 Taehee Yoo 2021-10-31 331 unregister_netdevice(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 332 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 333 }
b9022b53adad88 Taehee Yoo 2021-10-31 334
b9022b53adad88 Taehee Yoo 2021-10-31 335 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 336 err:
b9022b53adad88 Taehee Yoo 2021-10-31 337 dev_put(amt->stream_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 338 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 339 }
b9022b53adad88 Taehee Yoo 2021-10-31 340
b9022b53adad88 Taehee Yoo 2021-10-31 341 static void amt_dellink(struct net_device *dev, struct list_head *head)
b9022b53adad88 Taehee Yoo 2021-10-31 342 {
b9022b53adad88 Taehee Yoo 2021-10-31 343 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 344
b9022b53adad88 Taehee Yoo 2021-10-31 345 unregister_netdevice_queue(dev, head);
b9022b53adad88 Taehee Yoo 2021-10-31 346 netdev_upper_dev_unlink(amt->stream_dev, dev);
b9022b53adad88 Taehee Yoo 2021-10-31 347 dev_put(amt->stream_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 348 }
b9022b53adad88 Taehee Yoo 2021-10-31 349
b9022b53adad88 Taehee Yoo 2021-10-31 350 static size_t amt_get_size(const struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 351 {
b9022b53adad88 Taehee Yoo 2021-10-31 352 return nla_total_size(sizeof(__u32)) + /* IFLA_AMT_MODE */
b9022b53adad88 Taehee Yoo 2021-10-31 353 nla_total_size(sizeof(__u16)) + /* IFLA_AMT_RELAY_PORT */
b9022b53adad88 Taehee Yoo 2021-10-31 354 nla_total_size(sizeof(__u16)) + /* IFLA_AMT_GATEWAY_PORT */
b9022b53adad88 Taehee Yoo 2021-10-31 355 nla_total_size(sizeof(__u32)) + /* IFLA_AMT_LINK */
b9022b53adad88 Taehee Yoo 2021-10-31 356 nla_total_size(sizeof(__u32)) + /* IFLA_MAX_TUNNELS */
b9022b53adad88 Taehee Yoo 2021-10-31 357 nla_total_size(sizeof(struct iphdr)) + /* IFLA_AMT_DISCOVERY_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 358 nla_total_size(sizeof(struct iphdr)) + /* IFLA_AMT_REMOTE_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 359 nla_total_size(sizeof(struct iphdr)); /* IFLA_AMT_LOCAL_IP */
b9022b53adad88 Taehee Yoo 2021-10-31 360 }
b9022b53adad88 Taehee Yoo 2021-10-31 361
b9022b53adad88 Taehee Yoo 2021-10-31 362 static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 363 {
b9022b53adad88 Taehee Yoo 2021-10-31 364 struct amt_dev *amt = netdev_priv(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 365
b9022b53adad88 Taehee Yoo 2021-10-31 366 if (nla_put_u32(skb, IFLA_AMT_MODE, amt->mode))
b9022b53adad88 Taehee Yoo 2021-10-31 367 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 368 if (nla_put_be16(skb, IFLA_AMT_RELAY_PORT, amt->relay_port))
b9022b53adad88 Taehee Yoo 2021-10-31 369 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 370 if (nla_put_be16(skb, IFLA_AMT_GATEWAY_PORT, amt->gw_port))
b9022b53adad88 Taehee Yoo 2021-10-31 371 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 372 if (nla_put_u32(skb, IFLA_AMT_LINK, amt->stream_dev->ifindex))
b9022b53adad88 Taehee Yoo 2021-10-31 373 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 374 if (nla_put_in_addr(skb, IFLA_AMT_LOCAL_IP, amt->local_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 375 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 376 if (nla_put_in_addr(skb, IFLA_AMT_DISCOVERY_IP, amt->discovery_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 377 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 378 if (amt->remote_ip)
b9022b53adad88 Taehee Yoo 2021-10-31 379 if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, amt->remote_ip))
b9022b53adad88 Taehee Yoo 2021-10-31 380 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 381 if (nla_put_u32(skb, IFLA_AMT_MAX_TUNNELS, amt->max_tunnels))
b9022b53adad88 Taehee Yoo 2021-10-31 382 goto nla_put_failure;
b9022b53adad88 Taehee Yoo 2021-10-31 383
b9022b53adad88 Taehee Yoo 2021-10-31 384 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 385
b9022b53adad88 Taehee Yoo 2021-10-31 386 nla_put_failure:
b9022b53adad88 Taehee Yoo 2021-10-31 387 return -EMSGSIZE;
b9022b53adad88 Taehee Yoo 2021-10-31 388 }
b9022b53adad88 Taehee Yoo 2021-10-31 389
b9022b53adad88 Taehee Yoo 2021-10-31 390 static struct rtnl_link_ops amt_link_ops __read_mostly = {
b9022b53adad88 Taehee Yoo 2021-10-31 391 .kind = "amt",
b9022b53adad88 Taehee Yoo 2021-10-31 392 .maxtype = IFLA_AMT_MAX,
b9022b53adad88 Taehee Yoo 2021-10-31 393 .policy = amt_policy,
b9022b53adad88 Taehee Yoo 2021-10-31 394 .priv_size = sizeof(struct amt_dev),
b9022b53adad88 Taehee Yoo 2021-10-31 395 .setup = amt_link_setup,
b9022b53adad88 Taehee Yoo 2021-10-31 396 .validate = amt_validate,
b9022b53adad88 Taehee Yoo 2021-10-31 397 .newlink = amt_newlink,
b9022b53adad88 Taehee Yoo 2021-10-31 398 .dellink = amt_dellink,
b9022b53adad88 Taehee Yoo 2021-10-31 399 .get_size = amt_get_size,
b9022b53adad88 Taehee Yoo 2021-10-31 400 .fill_info = amt_fill_info,
b9022b53adad88 Taehee Yoo 2021-10-31 401 };
b9022b53adad88 Taehee Yoo 2021-10-31 402
b9022b53adad88 Taehee Yoo 2021-10-31 403 static struct net_device *amt_lookup_upper_dev(struct net_device *dev)
b9022b53adad88 Taehee Yoo 2021-10-31 404 {
b9022b53adad88 Taehee Yoo 2021-10-31 405 struct net_device *upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 406 struct amt_dev *amt;
b9022b53adad88 Taehee Yoo 2021-10-31 407
b9022b53adad88 Taehee Yoo 2021-10-31 408 for_each_netdev(dev_net(dev), upper_dev) {
b9022b53adad88 Taehee Yoo 2021-10-31 409 if (netif_is_amt(upper_dev)) {
b9022b53adad88 Taehee Yoo 2021-10-31 410 amt = netdev_priv(upper_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 411 if (amt->stream_dev == dev)
b9022b53adad88 Taehee Yoo 2021-10-31 412 return upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 413 }
b9022b53adad88 Taehee Yoo 2021-10-31 414 }
b9022b53adad88 Taehee Yoo 2021-10-31 415
b9022b53adad88 Taehee Yoo 2021-10-31 416 return NULL;
b9022b53adad88 Taehee Yoo 2021-10-31 417 }
b9022b53adad88 Taehee Yoo 2021-10-31 418
b9022b53adad88 Taehee Yoo 2021-10-31 419 static int amt_device_event(struct notifier_block *unused,
b9022b53adad88 Taehee Yoo 2021-10-31 420 unsigned long event, void *ptr)
b9022b53adad88 Taehee Yoo 2021-10-31 421 {
b9022b53adad88 Taehee Yoo 2021-10-31 422 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
b9022b53adad88 Taehee Yoo 2021-10-31 423 struct net_device *upper_dev;
b9022b53adad88 Taehee Yoo 2021-10-31 424 struct amt_dev *amt;
b9022b53adad88 Taehee Yoo 2021-10-31 425 LIST_HEAD(list);
b9022b53adad88 Taehee Yoo 2021-10-31 426 int new_mtu;
b9022b53adad88 Taehee Yoo 2021-10-31 427
b9022b53adad88 Taehee Yoo 2021-10-31 428 upper_dev = amt_lookup_upper_dev(dev);
b9022b53adad88 Taehee Yoo 2021-10-31 429 if (!upper_dev)
b9022b53adad88 Taehee Yoo 2021-10-31 430 return NOTIFY_DONE;
b9022b53adad88 Taehee Yoo 2021-10-31 431 amt = netdev_priv(upper_dev);
b9022b53adad88 Taehee Yoo 2021-10-31 432
b9022b53adad88 Taehee Yoo 2021-10-31 433 switch (event) {
b9022b53adad88 Taehee Yoo 2021-10-31 434 case NETDEV_UNREGISTER:
b9022b53adad88 Taehee Yoo 2021-10-31 435 amt_dellink(amt->dev, &list);
b9022b53adad88 Taehee Yoo 2021-10-31 436 unregister_netdevice_many(&list);
b9022b53adad88 Taehee Yoo 2021-10-31 437 break;
b9022b53adad88 Taehee Yoo 2021-10-31 438 case NETDEV_CHANGEMTU:
b9022b53adad88 Taehee Yoo 2021-10-31 439 if (amt->mode == AMT_MODE_RELAY)
b9022b53adad88 Taehee Yoo 2021-10-31 440 new_mtu = dev->mtu - AMT_RELAY_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 441 else
b9022b53adad88 Taehee Yoo 2021-10-31 442 new_mtu = dev->mtu - AMT_GW_HLEN;
b9022b53adad88 Taehee Yoo 2021-10-31 443
b9022b53adad88 Taehee Yoo 2021-10-31 444 dev_set_mtu(amt->dev, new_mtu);
b9022b53adad88 Taehee Yoo 2021-10-31 445 break;
b9022b53adad88 Taehee Yoo 2021-10-31 446 }
b9022b53adad88 Taehee Yoo 2021-10-31 447
b9022b53adad88 Taehee Yoo 2021-10-31 448 return NOTIFY_DONE;
b9022b53adad88 Taehee Yoo 2021-10-31 449 }
b9022b53adad88 Taehee Yoo 2021-10-31 450
b9022b53adad88 Taehee Yoo 2021-10-31 451 static struct notifier_block amt_notifier_block __read_mostly = {
b9022b53adad88 Taehee Yoo 2021-10-31 452 .notifier_call = amt_device_event,
b9022b53adad88 Taehee Yoo 2021-10-31 453 };
b9022b53adad88 Taehee Yoo 2021-10-31 454
b9022b53adad88 Taehee Yoo 2021-10-31 455 static int __init amt_init(void)
b9022b53adad88 Taehee Yoo 2021-10-31 456 {
b9022b53adad88 Taehee Yoo 2021-10-31 457 int err;
b9022b53adad88 Taehee Yoo 2021-10-31 458
b9022b53adad88 Taehee Yoo 2021-10-31 459 err = register_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 460 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 461 goto err;
b9022b53adad88 Taehee Yoo 2021-10-31 462
b9022b53adad88 Taehee Yoo 2021-10-31 463 err = rtnl_link_register(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 464 if (err < 0)
b9022b53adad88 Taehee Yoo 2021-10-31 465 goto unregister_notifier;
b9022b53adad88 Taehee Yoo 2021-10-31 466
b9022b53adad88 Taehee Yoo 2021-10-31 467 amt_wq = alloc_workqueue("amt", WQ_UNBOUND, 1);
b9022b53adad88 Taehee Yoo 2021-10-31 468 if (!amt_wq)
b9022b53adad88 Taehee Yoo 2021-10-31 469 goto rtnl_unregister;
b9022b53adad88 Taehee Yoo 2021-10-31 470
b9022b53adad88 Taehee Yoo 2021-10-31 471 return 0;
b9022b53adad88 Taehee Yoo 2021-10-31 472
b9022b53adad88 Taehee Yoo 2021-10-31 473 rtnl_unregister:
b9022b53adad88 Taehee Yoo 2021-10-31 474 rtnl_link_unregister(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 475 unregister_notifier:
b9022b53adad88 Taehee Yoo 2021-10-31 476 unregister_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 477 err:
b9022b53adad88 Taehee Yoo 2021-10-31 478 pr_err("error loading AMT module loaded\n");
b9022b53adad88 Taehee Yoo 2021-10-31 479 return err;
b9022b53adad88 Taehee Yoo 2021-10-31 480 }
b9022b53adad88 Taehee Yoo 2021-10-31 481 late_initcall(amt_init);
b9022b53adad88 Taehee Yoo 2021-10-31 482
b9022b53adad88 Taehee Yoo 2021-10-31 483 static void __exit amt_fini(void)
b9022b53adad88 Taehee Yoo 2021-10-31 484 {
b9022b53adad88 Taehee Yoo 2021-10-31 485 rtnl_link_unregister(&amt_link_ops);
b9022b53adad88 Taehee Yoo 2021-10-31 486 unregister_netdevice_notifier(&amt_notifier_block);
b9022b53adad88 Taehee Yoo 2021-10-31 487 destroy_workqueue(amt_wq);
b9022b53adad88 Taehee Yoo 2021-10-31 488 }
b9022b53adad88 Taehee Yoo 2021-10-31 489 module_exit(amt_fini);
b9022b53adad88 Taehee Yoo 2021-10-31 490
b9022b53adad88 Taehee Yoo 2021-10-31 491 MODULE_LICENSE("GPL");
b9022b53adad88 Taehee Yoo 2021-10-31 492 MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
b9022b53adad88 Taehee Yoo 2021-10-31 493 MODULE_ALIAS_RTNL_LINK("amt");
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-06-03 3:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-02 16:16 drivers/net/amt.c:2752 amt_rcv() error: we previously assumed 'amt' could be null (see line 2680) kernel test robot
2022-06-03 3:02 kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.