| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * vxcan.c - Virtual CAN Tunnel for cross namespace communication |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * for network interface pairs in a common and established way. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Copyright (c) 2017 Oliver Hartkopp <socketcan@hartkopp.net> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the version 2 of the GNU General Public License |
|---|
| 12 | | - * as published by the Free Software Foundation |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 17 | | - * GNU General Public License for more details. |
|---|
| 18 | | - * |
|---|
| 19 | | - * You should have received a copy of the GNU General Public License |
|---|
| 20 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 21 | 10 | */ |
|---|
| 22 | 11 | |
|---|
| 23 | 12 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 29 | 18 | #include <linux/can/dev.h> |
|---|
| 30 | 19 | #include <linux/can/skb.h> |
|---|
| 31 | 20 | #include <linux/can/vxcan.h> |
|---|
| 21 | +#include <linux/can/can-ml.h> |
|---|
| 32 | 22 | #include <linux/slab.h> |
|---|
| 33 | 23 | #include <net/rtnetlink.h> |
|---|
| 34 | 24 | |
|---|
| .. | .. |
|---|
| 151 | 141 | |
|---|
| 152 | 142 | static void vxcan_setup(struct net_device *dev) |
|---|
| 153 | 143 | { |
|---|
| 144 | + struct can_ml_priv *can_ml; |
|---|
| 145 | + |
|---|
| 154 | 146 | dev->type = ARPHRD_CAN; |
|---|
| 155 | 147 | dev->mtu = CANFD_MTU; |
|---|
| 156 | 148 | dev->hard_header_len = 0; |
|---|
| 157 | 149 | dev->addr_len = 0; |
|---|
| 158 | 150 | dev->tx_queue_len = 0; |
|---|
| 159 | | - dev->flags = (IFF_NOARP|IFF_ECHO); |
|---|
| 151 | + dev->flags = IFF_NOARP; |
|---|
| 160 | 152 | dev->netdev_ops = &vxcan_netdev_ops; |
|---|
| 161 | 153 | dev->needs_free_netdev = true; |
|---|
| 154 | + |
|---|
| 155 | + can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); |
|---|
| 156 | + can_set_ml_priv(dev, can_ml); |
|---|
| 162 | 157 | } |
|---|
| 163 | 158 | |
|---|
| 164 | 159 | /* forward declaration for rtnl_create_link() */ |
|---|
| .. | .. |
|---|
| 184 | 179 | |
|---|
| 185 | 180 | nla_peer = data[VXCAN_INFO_PEER]; |
|---|
| 186 | 181 | ifmp = nla_data(nla_peer); |
|---|
| 187 | | - err = rtnl_nla_parse_ifla(peer_tb, |
|---|
| 188 | | - nla_data(nla_peer) + |
|---|
| 189 | | - sizeof(struct ifinfomsg), |
|---|
| 190 | | - nla_len(nla_peer) - |
|---|
| 191 | | - sizeof(struct ifinfomsg), |
|---|
| 192 | | - NULL); |
|---|
| 182 | + err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack); |
|---|
| 193 | 183 | if (err < 0) |
|---|
| 194 | 184 | return err; |
|---|
| 195 | 185 | |
|---|
| .. | .. |
|---|
| 209 | 199 | return PTR_ERR(peer_net); |
|---|
| 210 | 200 | |
|---|
| 211 | 201 | peer = rtnl_create_link(peer_net, ifname, name_assign_type, |
|---|
| 212 | | - &vxcan_link_ops, tbp); |
|---|
| 202 | + &vxcan_link_ops, tbp, extack); |
|---|
| 213 | 203 | if (IS_ERR(peer)) { |
|---|
| 214 | 204 | put_net(peer_net); |
|---|
| 215 | 205 | return PTR_ERR(peer); |
|---|
| .. | .. |
|---|
| 294 | 284 | |
|---|
| 295 | 285 | static struct rtnl_link_ops vxcan_link_ops = { |
|---|
| 296 | 286 | .kind = DRV_NAME, |
|---|
| 297 | | - .priv_size = sizeof(struct vxcan_priv), |
|---|
| 287 | + .priv_size = ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN) + sizeof(struct can_ml_priv), |
|---|
| 298 | 288 | .setup = vxcan_setup, |
|---|
| 299 | 289 | .newlink = vxcan_newlink, |
|---|
| 300 | 290 | .dellink = vxcan_dellink, |
|---|