diff --git a/code/linux/include/linux/newip_route.h b/code/linux/include/linux/newip_route.h new file mode 100644 index 0000000000000000000000000000000000000000..d38c087369299a45afcd44a3bcbf6f8ae98ff10a --- /dev/null +++ b/code/linux/include/linux/newip_route.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * Based on include/uapi/linux/ipv6_route.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef _LINUX_NEWIP_ROUTE_H +#define _LINUX_NEWIP_ROUTE_H + +#include + +#endif + diff --git a/code/linux/include/linux/nip.h b/code/linux/include/linux/nip.h new file mode 100644 index 0000000000000000000000000000000000000000..d65846afd6ebd4d2231fd3f67f952bfdcd55dcfa --- /dev/null +++ b/code/linux/include/linux/nip.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Based on include/linux/ipv6.h + */ +#ifndef _NIP_H +#define _NIP_H + +#include +#include +#include +#include + +struct nip_devconf { + __s32 forwarding; + __s32 mtu; + __s32 ignore_routes_with_linkdown; + + __s32 disable_nip; + __s32 nndisc_notify; + __s32 use_oif_addrs_only; + __s32 keep_addr_on_down; + + struct ctl_table_header *sysctl_header; +}; + +/* This structure contains results of exthdrs parsing + * as offsets from skb->nh. + */ +#pragma pack(1) +struct ninet_skb_parm { + struct nip_addr dstaddr; + struct nip_addr srcaddr; + u8 nexthdr; +}; +#pragma pack() + +struct tcp_nip_request_sock { + struct tcp_request_sock tcp_nip_rsk_tcp; +}; + +struct nip_udp_sock { + struct udp_sock udp; +}; + +struct tcp_nip_sock { + struct tcp_sock tcp; +}; + +int find_nip_forward_stamp(struct net *net, void __user *arg); + +#endif /* _NIP_H */ diff --git a/code/linux/include/linux/nip_icmp.h b/code/linux/include/linux/nip_icmp.h new file mode 100644 index 0000000000000000000000000000000000000000..bb67221e2be007f64c3b9e4a27481e1a765cef94 --- /dev/null +++ b/code/linux/include/linux/nip_icmp.h @@ -0,0 +1,28 @@ +/* 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. + * + * Definitions for the NewIP ICMP protocol. + * + * Based on include/linux/icmp.h + */ +#ifndef _LINUX_NIP_ICMP_H +#define _LINUX_NIP_ICMP_H + +#include +#include +#include + +static inline struct nip_icmp_hdr *nip_icmp_header(const struct sk_buff *skb) +{ + return (struct nip_icmp_hdr *)skb_transport_header(skb); +} + +int nip_icmp_init(void); + +#endif diff --git a/code/linux/include/net/flow_nip.h b/code/linux/include/net/flow_nip.h new file mode 100644 index 0000000000000000000000000000000000000000..fe625d0b63d570fc418016d21e1aad0239d94a91 --- /dev/null +++ b/code/linux/include/net/flow_nip.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP Generic internet FLOW. + * + * Based on include/net/flow.h + */ +#ifndef _NET_FLOW_NIP_H +#define _NET_FLOW_NIP_H + +#include + +struct flow_nip { + struct flowi_common __fl_common; +#define flowin_oif __fl_common.flowic_oif +#define flowin_iif __fl_common.flowic_iif + struct nip_addr daddr; + struct nip_addr saddr; + union flowi_uli uli; +#define fln_sport uli.ports.sport +#define fln_dport uli.ports.dport +} __attribute__((__aligned__(BITS_PER_LONG / 8))); + +#endif diff --git a/code/linux/include/net/if_ninet.h b/code/linux/include/net/if_ninet.h new file mode 100644 index 0000000000000000000000000000000000000000..4e8876301b19173abf98e598209e1a5f2f598b3c --- /dev/null +++ b/code/linux/include/net/if_ninet.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP inet interface/address list definitions + * Linux NewIP INET implementation + * + * Based on include/net/if_inet6.h + */ +#ifndef _NET_IF_NINET_H +#define _NET_IF_NINET_H + +#include + +enum { + NINET_IFADDR_STATE_NEW, + NINET_IFADDR_STATE_DEAD, +}; + +struct ninet_ifaddr { + struct nip_addr addr; + + /* In seconds, relative to tstamp. Expiry is at tstamp + HZ * lft. */ + __u32 valid_lft; + __u32 preferred_lft; + refcount_t refcnt; + + /* protect one ifaddr itself */ + spinlock_t lock; + + int state; + + __u32 flags; + + unsigned long cstamp; /* created timestamp */ + unsigned long tstamp; /* updated timestamp */ + + struct ninet_dev *idev; + struct nip_rt_info *rt; + + struct hlist_node addr_lst; + struct list_head if_list; + + struct rcu_head rcu; +}; + +struct ninet_dev { + struct net_device *dev; + + struct list_head addr_list; + + rwlock_t lock; + refcount_t refcnt; + __u32 if_flags; + int dead; + + struct neigh_parms *nd_parms; + struct nip_devconf cnf; + + unsigned long tstamp; /* newip InterfaceTable update timestamp */ + struct rcu_head rcu; +}; + +#endif diff --git a/code/linux/include/net/netns/nip.h b/code/linux/include/net/netns/nip.h new file mode 100644 index 0000000000000000000000000000000000000000..ed9ceb2e2806d12e28e1fdd0a64c0881dc674559 --- /dev/null +++ b/code/linux/include/net/netns/nip.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP in net namespaces + * + * Based on include/net/netns/ipv6.h + */ +#ifndef __NETNS_NEWIP_H__ +#define __NETNS_NEWIP_H__ + +#include +#include + +struct ctl_table_header; + +struct netns_sysctl_newip { + int nip_rt_gc_interval; +}; +struct netns_newip { + uint32_t resv; + struct netns_sysctl_newip sysctl; + struct nip_devconf *devconf_dflt; + + struct nip_rt_info *nip_null_entry; + struct nip_rt_info *nip_broadcast_entry; + + struct dst_ops nip_dst_ops; + struct nip_fib_table *nip_fib_main_tbl; + struct nip_fib_table *nip_fib_local_tbl; +}; + +#endif + diff --git a/code/linux/include/net/ninet_connection_sock.h b/code/linux/include/net/ninet_connection_sock.h new file mode 100644 index 0000000000000000000000000000000000000000..1c13485ba677aa39ef6de86f180eaedb6599f8fc --- /dev/null +++ b/code/linux/include/net/ninet_connection_sock.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * NewIP NET + * Generic infrastructure for NewIP INET connection oriented protocols. + * + * Based on include/net/inet_connection_sock.h + */ +#ifndef _NINET_CONNECTION_SOCK_H +#define _NINET_CONNECTION_SOCK_H + +#include +#include +#include + +struct inet_bind_bucket; +struct request_sock; +struct sk_buff; +struct sock; +struct sockaddr; + +int ninet_csk_bind_conflict(const struct sock *sk, + const struct inet_bind_bucket *tb, bool relax); +int ninet_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); +void ninet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, + unsigned long timeout); + +#endif /* _NINET_CONNECTION_SOCK_H */ diff --git a/code/linux/include/net/ninet_hashtables.h b/code/linux/include/net/ninet_hashtables.h new file mode 100644 index 0000000000000000000000000000000000000000..3d959faa0e4ad7a0d9274accf61c489fd717b418 --- /dev/null +++ b/code/linux/include/net/ninet_hashtables.h @@ -0,0 +1,112 @@ +/* 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. + * + * Based on include/net/inet6_hashtables.h + */ +#ifndef NINET_HASHTABLES_H +#define NINET_HASHTABLES_H + +#if IS_ENABLED(CONFIG_NEWIP) +#include +#include +#include + +#include + +#include +#include + +struct inet_hashinfo; + +int ninet_hash(struct sock *sk); +void ninet_unhash(struct sock *sk); +int ninet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk); + +int __ninet_hash(struct sock *sk, struct sock *osk); + + +static inline unsigned int __ninet_ehashfn(const u32 lhash, + const u16 lport, + const u32 fhash, + const __be16 fport, + const u32 initval) +{ + const u32 ports = (((u32) lport) << 16) | (__force u32) fport; + + return jhash_3words(lhash, fhash, ports, initval); +} + +struct sock *__ninet_lookup_established(struct net *net, + struct inet_hashinfo *hashinfo, + const struct nip_addr *saddr, + const __be16 sport, + const struct nip_addr *daddr, + const u16 hnum, const int dif); + +struct sock *ninet_lookup_listener(struct net *net, + struct inet_hashinfo *hashinfo, + struct sk_buff *skb, int doff, + const struct nip_addr *saddr, + const __be16 sport, + const struct nip_addr *daddr, + const unsigned short hnum, const int dif, const int sdif); + +static inline struct sock *__ninet_lookup(struct net *net, + struct inet_hashinfo *hashinfo, + struct sk_buff *skb, int doff, + const struct nip_addr *saddr, + const __be16 sport, + const struct nip_addr *daddr, + const u16 hnum, + const int dif, bool *refcounted) +{ + struct sock *sk = __ninet_lookup_established(net, hashinfo, saddr, + sport, daddr, hnum, dif); + *refcounted = true; + if (sk) + return sk; + *refcounted = false; + return ninet_lookup_listener(net, hashinfo, skb, doff, saddr, sport, + daddr, hnum, dif, 0); +} + +static inline struct sock *__ninet_lookup_skb(struct inet_hashinfo *hashinfo, + struct sk_buff *skb, int doff, + const __be16 sport, + const __be16 dport, + int iif, bool *refcounted) +{ + struct sock *sk; + + *refcounted = true; + sk = skb_steal_sock(skb, refcounted); + if (sk) + return sk; + + return __ninet_lookup(dev_net(skb->dev), hashinfo, skb, + doff, &(NIPCB(skb)->srcaddr), sport, + &(NIPCB(skb)->dstaddr), ntohs(dport), + iif, refcounted); +} + +#define NINET_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \ + (((__sk)->sk_portpair == (__ports)) && \ + ((__sk)->sk_family == AF_NINET) && \ + nip_addr_eq(&(__sk)->sk_nip_daddr, (__saddr)) && \ + nip_addr_eq(&(__sk)->sk_nip_rcv_saddr, (__daddr)) && \ + (!(__sk)->sk_bound_dev_if || \ + ((__sk)->sk_bound_dev_if == (__dif))) && \ + net_eq(sock_net(__sk), (__net))) + +int ninet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk); + +#endif /* IS_ENABLED(CONFIG_NEWIP) */ +#endif /* _NINET_HASHTABLES_H */ diff --git a/code/linux/include/net/nip.h b/code/linux/include/net/nip.h new file mode 100644 index 0000000000000000000000000000000000000000..72257c16fe560185ed2242a9e4cbb3e62a833cd4 --- /dev/null +++ b/code/linux/include/net/nip.h @@ -0,0 +1,164 @@ +/* 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. + * + * Definitions for the NewIP module. + * + * Based on include/net/ip.h + * Based on include/net/protocol.h + */ +#ifndef _NET_NEWIP_H +#define _NET_NEWIP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "if_ninet.h" +#include "flow_nip.h" + +#define NIP_MAX_SOCKET_NUM 1024 + +struct ninet_protocol { + void (*early_demux)(struct sk_buff *skb); + + int (*handler)(struct sk_buff *skb); + + void (*err_handler)(struct sk_buff *skb, + struct ninet_skb_parm *opt, + u8 type, u8 code, int offset, __be32 info); + unsigned int flags; +}; + +#define NIPCB(skb) ((struct ninet_skb_parm *)&(TCP_SKB_CB(skb)->header.hnip)) + +extern const struct ninet_protocol __rcu *ninet_protos[MAX_INET_PROTOS]; + +int ninet_add_protocol(const struct ninet_protocol *prot, + unsigned char protocol); +int ninet_del_protocol(const struct ninet_protocol *prot, + unsigned char protocol); +int ninet_register_protosw(struct inet_protosw *p); +void ninet_unregister_protosw(struct inet_protosw *p); + +extern const struct proto_ops ninet_dgram_ops; +extern const struct proto_ops ninet_stream_ops; +extern struct neigh_table nnd_tbl; + +int tcp_nip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); +void tcp_nip_actual_send_reset(struct sock *sk, struct sk_buff *skb, u32 seq, + u32 ack_seq, u32 win, int rst, u32 priority); +int nip_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev); +struct nip_rt_info *nip_dst_alloc(struct net *net, struct net_device *dev, + int flags); + +static inline bool nip_addr_eq(const struct nip_addr *a1, + const struct nip_addr *a2) +{ + return (a1->bitlen == a2->bitlen) && (a1->bitlen <= NIP_ADDR_BIT_LEN_MAX) && + (memcmp(&a1->v.u, &a2->v.u, a1->bitlen >> 3) == 0); +}; + +static inline u32 nip_addr_hash(const struct nip_addr *a) +{ + u32 tmp[4]; + u8 len = a->bitlen >> 3; + + /* set unused bit to 0 */ + memset(tmp, 0, NIP_ADDR_BIT_LEN_16); + memcpy(tmp, &a->v.u, + len > NIP_ADDR_BIT_LEN_16 ? NIP_ADDR_BIT_LEN_16 : len); + + return (__force u32)(tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3]); +} + +int nip_send_skb(struct sk_buff *skb); + +void ninet_destroy_sock(struct sock *sk); +int nip_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); +int nip_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr, + int addr_len); +int nip_datagram_dst_update(struct sock *sk, bool fix_sk_saddr); +void nip_datagram_release_cb(struct sock *sk); +int ninet_add_protocol(const struct ninet_protocol *prot, + unsigned char protocol); +int ninet_eld_protocol(const struct ninet_protocol *prot, + unsigned char protocol); +int ninet_register_protosw(struct inet_protosw *p); +void ninet_unregister_protosw(struct inet_protosw *p); +int nip_input(struct sk_buff *skb); +int nip_output(struct net *net, struct sock *sk, struct sk_buff *skb); +int nip_forward(struct sk_buff *skb); + +unsigned int tcp_nip_sync_mss(struct sock *sk, u32 pmtu); +unsigned int tcp_nip_current_mss(struct sock *sk); +int tcp_nip_send_mss(struct sock *sk, int *size_goal, int flags); + +struct nip_addr *nip_nexthop(struct nip_rt_info *rt, struct nip_addr *daddr); +struct dst_entry *nip_sk_dst_lookup_flow(struct sock *sk, struct flow_nip *fln); +struct dst_entry *nip_dst_lookup_flow(struct net *net, const struct sock *sk, + struct flow_nip *fln, + const struct nip_addr *final_dst); +u_char *nip_get_mac(struct nip_addr *nipaddr, struct net_device *dev); +struct net_device *nip_get_defaultdev(void); +int nip_init_dev(void); + +int _nip_udp_output(struct sock *sk, void *from, int datalen, + int transhdrlen, const struct nip_addr *saddr, + ushort sport, const struct nip_addr *daddr, + ushort dport, struct dst_entry *dst); + +/* functions defined in nip_sockglue.c */ +int nip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, + unsigned int optlen); +int nip_getsockopt(struct sock *sk, int level, + int optname, char __user *optval, int __user *optlen); + +/* functions defined in nip_addrconf.c */ +int nip_addrconf_get_ifaddr(struct net *net, unsigned int cmd, void __user *arg); +/* 0 - No LOG + * 1 - Logging the kernel (for the official version) + * 2 - Logs are directly printed on the screen for debugging + */ +#define __NIP_DEBUG 0 + +#if __NIP_DEBUG >= 2 +#define TRACE_OUT(fmt, ...) \ + do { \ + pr_crit("%s:%s:%d", __FILE__, __func__, __LINE__); \ + pr_crit(fmt, ##__VA_ARGS__); \ + pr_crit("\n"); \ + } while (0) +#define TRACE(fmt, ...) pr_crit(fmt, ##__VA_ARGS__) +#elif __NIP_DEBUG >= 1 +#define TRACE_OUT(fmt, ...) \ + do { \ + pr_warn("%s:%s:%d", __FILE__, __func__, __LINE__); \ + pr_warn(fmt, ##__VA_ARGS__); \ + pr_warn("\n"); \ + } while (0) +#define TRACE(fmt, ...) pr_warn(fmt, ##__VA_ARGS__) +#else +#define TRACE(fmt, ...) +#define TRACE_OUT(fmt, ...) +#endif + +#define DEBUG(format, ...) TRACE(format, ##__VA_ARGS__) +#define DEBUG_TRACE(format, ...) TRACE_OUT(format, ##__VA_ARGS__) + +#endif diff --git a/code/linux/include/net/nip_fib.h b/code/linux/include/net/nip_fib.h new file mode 100644 index 0000000000000000000000000000000000000000..d653f5694c628e11e382865fd8b7328a7f5bb0c4 --- /dev/null +++ b/code/linux/include/net/nip_fib.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Linux NewIP INET implementation + * + * Based on include/net/ip6_fib.h + */ +#ifndef _NET_NEWIP_FIB_H +#define _NET_NEWIP_FIB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "nip.h" +#include "flow_nip.h" + +#define NIN_ROUTE_HSIZE_SHIFT 4 +#define NIN_ROUTE_HSIZE (1 << NIN_ROUTE_HSIZE_SHIFT) + +struct nip_fib_config { + u32 fc_table; + u32 fc_metric; + int fc_ifindex; + u32 fc_flags; + u32 fc_protocol; + u32 fc_type; /* only 8 bits are used */ + + struct nip_addr fc_dst; + struct nip_addr fc_src; + struct nip_addr fc_gateway; + + struct nl_info fc_nlinfo; + unsigned long fc_expires; +}; + +struct nip_fib_node { + struct hlist_node fib_hlist; + struct nip_rt_info *nip_route_info; + struct rcu_head rcu; +}; + +struct nip_fib_table; + +struct nip_rt_info { + struct dst_entry dst; + struct dst_entry *from; + struct nip_fib_table *rt_table; + struct nip_fib_node __rcu *rt_node; + struct ninet_dev *rt_idev; + struct nip_rt_info *__percpu *rt_pcpu; + + atomic_t rt_ref; + + uint32_t rt_flags; + struct nip_addr gateway; + struct nip_addr rt_dst; + struct nip_addr rt_src; + + u32 rt_metric; + u32 rt_pmtu; + u8 rt_protocol; +}; + +static inline struct ninet_dev *nip_dst_idev(struct dst_entry *dst) +{ + return ((struct nip_rt_info *)dst)->rt_idev; +} + +struct nip_fib_table { + u32 nip_tb_id; + spinlock_t nip_tb_lock; + struct hlist_head nip_tb_head[NIN_ROUTE_HSIZE]; + unsigned int flags; +}; + +#define NIP_RT_TABLE_MAIN RT_TABLE_MAIN +#define NIP_RT_TABLE_LOCAL RT_TABLE_LOCAL + +typedef struct nip_rt_info *(*nip_pol_lookup_t) (struct net *, + struct nip_fib_table *, + struct flow_nip *, int); + +struct nip_fib_table *nip_fib_get_table(struct net *net, u32 id); + +struct dst_entry *nip_fib_rule_lookup(struct net *net, struct flow_nip *fln, + int flags, nip_pol_lookup_t lookup); + +#define NIP_RT_EXPIRES_FLAGS 12 +static inline void nip_rt_set_expires(struct nip_rt_info *rt, + unsigned long expires) +{ + rt->dst.expires = expires; + + rt->rt_flags |= NIP_RT_EXPIRES_FLAGS; +} + +static inline void nip_rt_clean_expires(struct nip_rt_info *rt) +{ + rt->rt_flags &= ~NIP_RT_EXPIRES_FLAGS; + rt->dst.expires = 0; +} + +static inline void nip_rt_put(struct nip_rt_info *rt) +{ + BUILD_BUG_ON(offsetof(struct nip_rt_info, dst) != 0); + dst_release(&rt->dst); +} + +void nip_rt_free_pcpu(struct nip_rt_info *non_pcpu_rt); + +static inline void nip_rt_hold(struct nip_rt_info *rt) +{ + atomic_inc(&rt->rt_ref); +} + +static inline void nip_rt_release(struct nip_rt_info *rt) +{ + if (atomic_dec_and_test(&rt->rt_ref)) { + nip_rt_free_pcpu(rt); + dst_dev_put(&rt->dst); + + dst_release(&rt->dst); + } +} + +int nip_fib_init(void); + +void nip_fib_gc_cleanup(void); + +struct nip_fib_node *nip_fib_locate(struct hlist_head *nip_tb_head, + const struct nip_addr *daddr); + +void nip_fib_clean_all(struct net *net, + int (*func)(struct nip_rt_info *, void *arg), void *arg); + +int nip_fib_add(struct hlist_head *nip_tb_head, struct nip_rt_info *rt); + +int nip_fib_del(struct nip_rt_info *rt_info, struct nl_info *info); + +int nip_set_route_netlink(struct net *net, struct nip_rtmsg *rtmsg); + +int nip_del_route_netlink(struct net *net, struct nip_rtmsg *rtmsg); + +#endif /* _NET_NEWIP_FIB_H */ diff --git a/code/linux/include/net/nip_route.h b/code/linux/include/net/nip_route.h new file mode 100644 index 0000000000000000000000000000000000000000..0cc11e15a5464b020a0331431e0d1e8513438ee9 --- /dev/null +++ b/code/linux/include/net/nip_route.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Based on include/net/ip6_route.h + */ +#ifndef _NET_NIP_ROUTE_H +#define _NET_NIP_ROUTE_H + +#include +#include "nip_fib.h" +#include "nip_addrconf.h" + +#define NIP_RT_PRIO_USER 1024 + +struct nip_rt_info *nip_addrconf_dst_alloc(struct ninet_dev *idev, + const struct nip_addr *addr); + + +void nip_route_input(struct sk_buff *skb); +struct dst_entry *nip_route_input_lookup(struct net *net, + struct net_device *dev, + struct flow_nip *fln, int flags); + +struct dst_entry *nip_route_output_flags(struct net *net, const struct sock *sk, + struct flow_nip *fln, int flags); + + +static inline struct dst_entry *nip_route_output(struct net *net, + const struct sock *sk, + struct flow_nip *fln) +{ + return nip_route_output_flags(net, sk, fln, 0); +} + +struct nip_rt_info *nip_pol_route(struct net *net, struct nip_fib_table *table, + int oif, struct flow_nip *fln, int flags); + +bool nip_bind_addr_check(struct net *net, + struct nip_addr *addr); + +int nip_ins_rt(struct nip_rt_info *rt); +int nip_del_rt(struct nip_rt_info *rt); + +static inline int nip_route_get_saddr(struct net *net, struct nip_rt_info *rt, + const struct nip_addr *daddr, + struct nip_addr *saddr) +{ + struct ninet_dev *idev = + rt ? nip_dst_idev((struct dst_entry *)rt) : NULL; + int err = 0; + + err = nip_dev_get_saddr(net, idev ? idev->dev : NULL, daddr, saddr); + + return err; +} + +void nip_rt_ifdown(struct net *net, struct net_device *dev); + +int nip_route_ioctl(struct net *net, unsigned int cmd, struct nip_rtmsg *rtmsg); + +int nip_route_init(void); + +void nip_route_cleanup(void); + +#endif /*_NET_NIP_ROUTE_H*/ diff --git a/code/linux/include/net/nip_udp.h b/code/linux/include/net/nip_udp.h new file mode 100644 index 0000000000000000000000000000000000000000..571de5a45ffb0ef5e4f639c1d8aff0c7a56383f9 --- /dev/null +++ b/code/linux/include/net/nip_udp.h @@ -0,0 +1,33 @@ +/* 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. + * + * Definitions for the NewIP UDP module. + * + * Based on include/net/udp.h + */ +#ifndef _NET_NEWIP_UDP_H +#define _NET_NEWIP_UDP_H + +#include +#include +#include +#include +#include + +#define NIP_UDP_HSLOT_COUNT 10 + +int nip_udp_init(void); + +int nip_udp_output(struct sock *sk, struct msghdr *msg, size_t len); + +int nip_udp_input(struct sk_buff *skb); +int nip_udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, + int noblock, int flags, int *addr_len); + +#endif diff --git a/code/linux/include/net/nndisc.h b/code/linux/include/net/nndisc.h new file mode 100644 index 0000000000000000000000000000000000000000..5da370b78cdfd6642a6f37f195477396f05e6974 --- /dev/null +++ b/code/linux/include/net/nndisc.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Based on include/net/ndisc.h + */ +#ifndef _NNDISC_H +#define _NNDISC_H + +#include +#include +#include +#include +#include +#include +#include + +#define NEWIP_NEIGH_BUCKET_MAX 8 +extern struct neigh_table nnd_tbl; + +#define NIP_ARP_NS 0x01 /* ARP request */ +#define NIP_ARP_NA 0x02 /* ARP response */ + +struct nnd_msg { + struct nip_icmp_hdr icmph; + __u8 data[0]; +}; + +static inline bool neigh_key_eq800(const struct neighbour *n, const void *pkey) +{ + struct nip_addr *a1, *a2; + + a1 = (struct nip_addr *)(pkey); + a2 = (struct nip_addr *)(n->primary_key); + +#define RIGHT_POS_3 3 + return a1->bitlen == a2->bitlen && a1->bitlen <= NIP_ADDR_BIT_LEN_MAX && + memcmp(&a1->v.u, &a2->v.u, a1->bitlen >> RIGHT_POS_3) == 0; +} + +static inline u32 nndisc_hashfn(const void *pkey, const struct net_device *dev, + __u32 *hash_rnd) +{ + return (*(int *)pkey % NEWIP_NEIGH_BUCKET_MAX); +} + +static inline struct neighbour *__nip_neigh_lookup_noref(struct net_device *dev, + const void *pkey) +{ + return ___neigh_lookup_noref(&nnd_tbl, neigh_key_eq800, nndisc_hashfn, + pkey, dev); +} + +static inline struct neighbour *__nip_neigh_lookup(struct net_device *dev, + const void *pkey) +{ + struct neighbour *n; + + rcu_read_lock_bh(); + n = __nip_neigh_lookup_noref(dev, pkey); + if (n && !refcount_inc_not_zero(&n->refcnt)) + n = NULL; + rcu_read_unlock_bh(); + + return n; +} + +int nndisc_rcv(struct sk_buff *skb); + +int nndisc_init(void); + +#endif diff --git a/code/linux/include/net/tcp_nip.h b/code/linux/include/net/tcp_nip.h new file mode 100644 index 0000000000000000000000000000000000000000..1e39fd5b64e4435c6cc43d6dd53ce074d5c2d6b0 --- /dev/null +++ b/code/linux/include/net/tcp_nip.h @@ -0,0 +1,182 @@ +/* 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. + * + * Definitions for the NewIP TCP module. + * + * Based on include/net/tcp.h + */ +#ifndef _TCP_NIP_H +#define _TCP_NIP_H + +#define FASTRETRANS_DEBUG 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern struct proto tcp_nip_prot; + +#define TCP_HDR_LEN_OFFSET 6 +#define TCP_HDR_LEN_POS_PAYLOAD 12 +#define TCP_NIP_4BYTE_PAYLOAD 2 + +#define TCP_OPT_MSS_PAYLOAD 24 +#define TCP_OLEN_MSS_PAYLOAD 16 + +#define TCP_NUM_2 2 +#define TCP_NUM_4 4 + +#define TCP_ARRAY_INDEX_2 2 + +#define TCP_NIP_KEEPALIVE_CYCLE_MS_DIVISOR 20 /* 1 HZ = 1 seconds */ +#define TCP_NIP_CSK_KEEPALIVE_CYCLE 10 /* 1 HZ = 1 seconds */ + +#define TCP_NIP_WINDOW_MAX 65535U + +/* init */ +int tcp_nip_init(void); +void tcp_nip_exit(void); + +void tcp_nip_done(struct sock *sk); +int tcp_direct_connect(struct sock *sk, void __user *arg); +void tcp_nip_rcv_established( + struct sock *sk, + struct sk_buff *skb, + const struct tcphdr *th, + unsigned int len); + +void __tcp_nip_push_pending_frames( + struct sock *sk, + unsigned int cur_mss, + int nonagle); + +u32 __nip_tcp_select_window(struct sock *sk); +unsigned short nip_get_output_checksum_tcp(struct sk_buff *skb, struct nip_addr src_addr, + struct nip_addr dst_addr); +void tcp_nip_rearm_rto(struct sock *sk); + +int tcp_nip_rcv_state_process(struct sock *sk, struct sk_buff *skb); + +/* tcp_nip_output */ +int tcp_nip_transmit_skb( + struct sock *sk, + struct sk_buff *skb, + int clone_it, + gfp_t gfp_mask); +int __tcp_nip_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); +int tcp_nip_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs); +void tcp_nip_send_fin(struct sock *sk); +void tcp_nip_send_active_reset(struct sock *sk, gfp_t priority); +void tcp_nip_send_probe0(struct sock *sk); +int tcp_nip_write_wakeup(struct sock *sk, int mib); + +/* tcp_nip_timer */ +void tcp_nip_init_xmit_timers(struct sock *sk); +void tcp_nip_clear_xmit_timers(struct sock *sk); +void tcp_nip_delack_timer_handler(struct sock *sk); +void tcp_nip_write_timer_handler(struct sock *sk); + +/* check probe0 timer */ +static inline void tcp_nip_check_probe_timer(struct sock *sk) +{ + if (!tcp_sk(sk)->packets_out && !inet_csk(sk)->icsk_pending) + inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0, + tcp_probe0_base(sk), TCP_RTO_MAX); +} + +static inline struct sk_buff *tcp_nip_send_head(const struct sock *sk) +{ + return sk->sk_send_head; +} + +static inline void tcp_nip_add_write_queue_tail( + struct sock *sk, + struct sk_buff *skb) +{ + __skb_queue_tail(&sk->sk_write_queue, skb); + + if (sk->sk_send_head == NULL) + sk->sk_send_head = skb; +} + +static inline void tcp_nip_write_queue_purge(struct sock *sk) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { + tcp_skb_tsorted_anchor_cleanup(skb); + sk_wmem_free_skb(sk, skb); + } + + tcp_clear_all_retrans_hints(tcp_sk(sk)); + sk->sk_send_head = NULL; + inet_csk(sk)->icsk_backoff = 0; +} + +static inline bool tcp_nip_write_queue_empty(struct sock *sk) +{ + return skb_queue_empty(&sk->sk_write_queue); +} + +/* connect */ +int __tcp_nip_connect(struct sock *sk); +int tcp_newip_conn_request(struct request_sock_ops *rsk_ops, + const struct tcp_request_sock_ops *af_ops, + struct sock *sk, struct sk_buff *skb); +struct sk_buff *tcp_nip_make_synack( + const struct sock *sk, + struct dst_entry *dst, + struct request_sock *req, + struct tcp_fastopen_cookie *foc, + enum tcp_synack_type synack_type); +int nip_send_synack(struct request_sock *req, struct sk_buff *skb); +struct sock *tcp_nip_check_req(struct sock *sk, struct sk_buff *skb, + struct request_sock *req); +int tcp_nip_child_process(struct sock *parent, struct sock *child, + struct sk_buff *skb); +int tcp_nip_rtx_synack(const struct sock *sk, struct request_sock *req); + +/* client send ack */ +void tcp_nip_send_ack(struct sock *sk); +struct sock *tcp_nip_create_openreq_child(const struct sock *sk, + struct request_sock *req, + struct sk_buff *skb); +void tcp_nip_initialize_rcv_mss(struct sock *sk); + +/* release */ +void tcp_nip_release_cb(struct sock *sk); + +void tcp_nip_keepalive_enable(struct sock *sk); +void tcp_nip_keepalive_disable(struct sock *sk); + +#endif /* _NIP_TCP_H */ diff --git a/code/linux/include/net/transp_nip.h b/code/linux/include/net/transp_nip.h new file mode 100644 index 0000000000000000000000000000000000000000..2688e55f5f7799e5ed816cb117e878f247985961 --- /dev/null +++ b/code/linux/include/net/transp_nip.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * Based on include/net/transp_v6.h + */ +#ifndef _TRANSP_NIP_H +#define _TRANSP_NIP_H + +extern struct proto nip_udp_prot; + +int nip_udp_init(void); +void nip_udp_exit(void); + +int nip_udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); + +void nip_datagram_recv_ctl(struct sock *sk, struct msghdr *msg, + struct sk_buff *skb); +void nip_datagram_recv_common_ctl(struct sock *sk, struct msghdr *msg, + struct sk_buff *skb); +void nip_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg, + struct sk_buff *skb); + +void nip_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp, __u16 srcp, + __u16 destp, int bucket); + +void ninet_destroy_sock(struct sock *sk); + +#define NEWIP_SEQ_DGRAM_HEADER \ + " s1 " \ + "local_address " \ + "remote_address " \ + "st tx_queue rc_queue tr tm->when retrnsmt" \ + " uid timeout inode ref pointer drops\n" + +#endif