diff --git a/src/linux/include/net/if_ninet.h b/src/linux/include/net/if_ninet.h index 4e8876301b19173abf98e598209e1a5f2f598b3c..8172f7393c4c18d5c8e44cc91112604f5900949b 100644 --- a/src/linux/include/net/if_ninet.h +++ b/src/linux/include/net/if_ninet.h @@ -61,4 +61,6 @@ struct ninet_dev { struct rcu_head rcu; }; +void devninet_init(void); + #endif diff --git a/src/linux/net/newip/Makefile b/src/linux/net/newip/Makefile index 12a3cbf215d8208f7c34f9eadb55a93eff694d40..be2ee00d5bc19baf8bab12809687930bcdcd7877 100644 --- a/src/linux/net/newip/Makefile +++ b/src/linux/net/newip/Makefile @@ -8,7 +8,7 @@ # net/newip/Makefile obj-$(CONFIG_NEWIP) += newip.o -newip-objs := nip_addr.o nip_hdr_encap.o nip_hdr_decap.o nip_checksum.o af_ninet.o nip_input.o udp.o protocol.o nip_output.o nip_addrconf.o nip_addrconf_core.o route.o nip_fib.o nip_fib_rules.o nndisc.o icmp.o tcp_nip_parameter.o +newip-objs := nip_addr.o nip_hdr_encap.o nip_hdr_decap.o nip_checksum.o af_ninet.o nip_input.o udp.o protocol.o nip_output.o nip_addrconf.o nip_addrconf_core.o route.o nip_fib.o nip_fib_rules.o nndisc.o icmp.o tcp_nip_parameter.o devninet.o newip-objs += tcp_nip.o ninet_connection_sock.o ninet_hashtables.o tcp_nip_output.o tcp_nip_input.o tcp_nip_timer.o nip_sockglue.o newip-objs += nip_hooks_register.o diff --git a/src/linux/net/newip/af_ninet.c b/src/linux/net/newip/af_ninet.c index 480e7c2d20ca80c4e0a1626133097be6c4376e7e..65266580c4fc362294db892b87bc0e8db683d73d 100644 --- a/src/linux/net/newip/af_ninet.c +++ b/src/linux/net/newip/af_ninet.c @@ -733,6 +733,8 @@ static int __init ninet_init(void) goto nip_packet_fail; } + devninet_init(); + #ifdef CONFIG_NEWIP_HOOKS err = ninet_hooks_register(); if (err) { diff --git a/src/linux/net/newip/devninet.c b/src/linux/net/newip/devninet.c new file mode 100644 index 0000000000000000000000000000000000000000..5363305a0c892665df2fb303bf7410a644b5f4b0 --- /dev/null +++ b/src/linux/net/newip/devninet.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP INET + * An implementation of the TCP/IP protocol suite for the LINUX + * operating system. NewIP INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * DEVICE - NEWIP device support. + * Based on net/ipv4/devinet.c + */ +#include +#include +#include +#include +#include + +static int ninet_gifconf(struct net_device *dev, char __user *buf, int len, int size) +{ + struct ninet_dev *nin_dev = __nin_dev_get(dev); + const struct ninet_ifaddr *ifa; + struct ifreq ifr; + int done = 0; + + if (WARN_ON(size > sizeof(struct ifreq))) + goto out; + if (!nin_dev) + goto out; + + list_for_each_entry(ifa, &nin_dev->addr_list, if_list) { + ifa = rcu_dereference_protected(ifa, lockdep_is_held(&ifa->lock)); + if (!ifa) { + done = -EFAULT; + break; + } + if (!buf) { + done += size; + continue; + } + if (len < size) + break; + memset(&ifr, 0, sizeof(struct ifreq)); + strcpy(ifr.ifr_name, ifa->rt->dst.dev->name); + + (*(struct sockaddr_nin *)&ifr.ifr_addr).sin_family = AF_NINET; + memcpy(&((struct sockaddr_nin *)&ifr.ifr_addr)->sin_addr, &ifa->addr, + sizeof(struct nip_addr)); + + if (copy_to_user(buf + done, &ifr, size)) { + done = -EFAULT; + break; + } + len -= size; + done += size; + } +out: + return done; +} + +void __init devninet_init(void) +{ + int err; + + err = register_gifconf(PF_NINET, ninet_gifconf); + if (err < 0) + DEBUG("%s: ninet_gifconf register fail!\n", __func__); +} +