210 lines
6.6 KiB
Diff
210 lines
6.6 KiB
Diff
Author: Pavithra R <pavir@codeaurora.org>
|
|
Date: Sat Aug 1 13:27:20 2020 +0530
|
|
|
|
nat46: Export APIs for acceleration engine support in nat46 for kernel 5.4
|
|
|
|
This patch is propagated from kernel 4.4 commit
|
|
861e64a607fd22d5af089cf56539f42a2e31d581
|
|
|
|
The patch defines and exports APIs in nat46 to be used for accelaration.
|
|
|
|
Change-Id: I7934b15544953f870d3595b8b359433b4fff7c30
|
|
Signed-off-by: Pavithra R <pavir@codeaurora.org>
|
|
|
|
--- a/nat46/modules/nat46-core.c
|
|
+++ b/nat46/modules/nat46-core.c
|
|
@@ -1497,7 +1497,6 @@ static uint16_t nat46_fixup_icmp_dest_un
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
/* Fixup ICMP->ICMP6 before IP header translation, according to http://tools.ietf.org/html/rfc6145 */
|
|
|
|
static uint16_t nat46_fixup_icmp(nat46_instance_t *nat46, struct iphdr *iph, struct sk_buff *old_skb) {
|
|
@@ -1579,6 +1578,10 @@ int pairs_xlate_v6_to_v4_outer(nat46_ins
|
|
return ( (xlate_src >= 0) && (xlate_dst >= 0) );
|
|
}
|
|
|
|
+int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr) {
|
|
+ return pairs_xlate_v6_to_v4_outer(netdev_nat46_instance(dev), ip6h, proto, pv4saddr, pv4daddr);
|
|
+}
|
|
+EXPORT_SYMBOL(xlate_6_to_4);
|
|
|
|
int nat46_ipv6_input(struct sk_buff *old_skb) {
|
|
struct ipv6hdr *ip6h = ipv6_hdr(old_skb);
|
|
@@ -1733,6 +1736,10 @@ int nat46_ipv6_input(struct sk_buff *old
|
|
|
|
nat46debug(5, "about to send v4 packet, flags: %02x", IPCB(new_skb)->flags);
|
|
nat46_netdev_count_xmit(new_skb, old_skb->dev);
|
|
+
|
|
+ /* set skb->iif */
|
|
+ new_skb->skb_iif = old_skb->skb_iif;
|
|
+
|
|
netif_rx(new_skb);
|
|
|
|
/* TBD: should copy be released here? */
|
|
@@ -1841,6 +1848,10 @@ int pairs_xlate_v4_to_v6_outer(nat46_ins
|
|
return 0;
|
|
}
|
|
|
|
+int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr) {
|
|
+ return pairs_xlate_v4_to_v6_outer(netdev_nat46_instance(dev), hdr4, &sport, &dport, v6saddr, v6daddr);
|
|
+}
|
|
+EXPORT_SYMBOL(xlate_4_to_6);
|
|
|
|
int nat46_ipv4_input(struct sk_buff *old_skb) {
|
|
nat46_instance_t *nat46 = get_nat46_instance(old_skb);
|
|
@@ -1981,6 +1992,10 @@ int nat46_ipv4_input(struct sk_buff *old
|
|
|
|
nat46debug(5, "about to send v6 packet, flags: %02x", IP6CB(new_skb)->flags);
|
|
nat46_netdev_count_xmit(new_skb, old_skb->dev);
|
|
+
|
|
+ /* set skb->iif */
|
|
+ new_skb->skb_iif = old_skb->skb_iif;
|
|
+
|
|
netif_rx(new_skb);
|
|
|
|
done:
|
|
@@ -1988,4 +2003,22 @@ done:
|
|
return err;
|
|
}
|
|
|
|
+int nat46_get_npairs(struct net_device *dev) {
|
|
+ nat46_instance_t *nat46 = netdev_nat46_instance(dev);
|
|
+ return nat46->npairs;
|
|
+}
|
|
+EXPORT_SYMBOL(nat46_get_npairs);
|
|
|
|
+bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count) {
|
|
+ nat46_instance_t *nat46 = netdev_nat46_instance(dev);
|
|
+ if (nat46->npairs < 1) {
|
|
+ /*
|
|
+ * no rules ?
|
|
+ */
|
|
+ return false;
|
|
+ }
|
|
+ *count = nat46->npairs;
|
|
+ *nat46_rule_pair = nat46->pairs;
|
|
+ return true;
|
|
+}
|
|
+EXPORT_SYMBOL(nat46_get_rule_config);
|
|
--- a/nat46/modules/nat46-core.h
|
|
+++ b/nat46/modules/nat46-core.h
|
|
@@ -42,18 +42,18 @@ typedef enum {
|
|
#define NAT46_SIGNATURE 0x544e3634
|
|
#define FREED_NAT46_SIGNATURE 0xdead544e
|
|
|
|
-typedef struct {
|
|
+typedef struct nat46_xlate_rule {
|
|
nat46_xlate_style_t style;
|
|
struct in6_addr v6_pref;
|
|
- int v6_pref_len;
|
|
- u32 v4_pref;
|
|
- int v4_pref_len;
|
|
- int ea_len;
|
|
- int psid_offset;
|
|
- int fmr_flag;
|
|
+ int v6_pref_len;
|
|
+ u32 v4_pref;
|
|
+ int v4_pref_len;
|
|
+ int ea_len;
|
|
+ int psid_offset;
|
|
+ int fmr_flag;
|
|
} nat46_xlate_rule_t;
|
|
|
|
-typedef struct {
|
|
+typedef struct nat46_xlate_rulepair {
|
|
nat46_xlate_rule_t local;
|
|
nat46_xlate_rule_t remote;
|
|
} nat46_xlate_rulepair_t;
|
|
@@ -82,4 +82,9 @@ nat46_instance_t *get_nat46_instance(str
|
|
nat46_instance_t *alloc_nat46_instance(int npairs, nat46_instance_t *old, int from_ipair, int to_ipair, int remove_ipair);
|
|
void release_nat46_instance(nat46_instance_t *nat46);
|
|
|
|
+int xlate_6_to_4(struct net_device *dev, struct ipv6hdr *ip6h, uint16_t proto, __u32 *pv4saddr, __u32 *pv4daddr);
|
|
+int xlate_4_to_6(struct net_device *dev, struct iphdr *hdr4, uint16_t sport, uint16_t dport, void *v6saddr, void *v6daddr);
|
|
+bool nat46_get_rule_config(struct net_device *dev, nat46_xlate_rulepair_t **nat46_rule_pair, int *count);
|
|
+int nat46_get_npairs(struct net_device *dev);
|
|
+
|
|
#endif
|
|
--- a/nat46/modules/nat46-netdev.c
|
|
+++ b/nat46/modules/nat46-netdev.c
|
|
@@ -24,10 +24,12 @@
|
|
#include <net/ip6_route.h>
|
|
#include <net/ipv6.h>
|
|
#include <linux/version.h>
|
|
+#include <linux/radix-tree.h>
|
|
#include "nat46-core.h"
|
|
#include "nat46-module.h"
|
|
|
|
#define NETDEV_DEFAULT_NAME "nat46."
|
|
+static RADIX_TREE(netdev_tree, GFP_ATOMIC);
|
|
|
|
typedef struct {
|
|
u32 sig;
|
|
@@ -83,6 +85,18 @@ void nat46_netdev_count_xmit(struct sk_b
|
|
dev->stats.tx_bytes += skb->len;
|
|
}
|
|
|
|
+void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes,
|
|
+ uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_dropped, uint32_t tx_dropped)
|
|
+{
|
|
+ dev->stats.rx_packets += rx_packets;
|
|
+ dev->stats.rx_bytes += rx_bytes;
|
|
+ dev->stats.tx_packets += tx_packets;
|
|
+ dev->stats.tx_bytes += tx_bytes;
|
|
+ dev->stats.rx_dropped += rx_dropped;
|
|
+ dev->stats.tx_dropped += tx_dropped;
|
|
+}
|
|
+EXPORT_SYMBOL(nat46_update_stats);
|
|
+
|
|
void *netdev_nat46_instance(struct net_device *dev) {
|
|
nat46_netdev_priv_t *priv = netdev_priv(dev);
|
|
return priv->nat46;
|
|
@@ -160,6 +174,11 @@ int nat46_netdev_create(struct net *net,
|
|
printk("nat46: netdevice nat46 '%s' created successfully.\n", devname);
|
|
kfree(devname);
|
|
|
|
+ /*
|
|
+ * add this netdevice to list
|
|
+ */
|
|
+ radix_tree_insert(&netdev_tree, (*dev)->ifindex, (void *)*dev);
|
|
+
|
|
return 0;
|
|
|
|
err_register_dev:
|
|
@@ -176,10 +195,24 @@ void nat46_netdev_destroy(struct net_dev
|
|
netif_stop_queue(dev);
|
|
netdev_nat46_set_instance(dev, NULL);
|
|
unregister_netdev(dev);
|
|
+ radix_tree_delete(&netdev_tree, dev->ifindex);
|
|
free_netdev(dev);
|
|
printk("nat46: Destroying nat46 device.\n");
|
|
}
|
|
|
|
+bool is_map_t_dev(struct net_device *dev)
|
|
+{
|
|
+ if(!dev) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if(radix_tree_lookup(&netdev_tree, dev->ifindex)) {
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+EXPORT_SYMBOL(is_map_t_dev);
|
|
+
|
|
static int is_nat46(struct net_device *dev) {
|
|
nat46_netdev_priv_t *priv = netdev_priv(dev);
|
|
return (priv && (NAT46_DEVICE_SIGNATURE == priv->sig));
|
|
--- a/nat46/modules/nat46-netdev.h
|
|
+++ b/nat46/modules/nat46-netdev.h
|
|
@@ -26,3 +26,6 @@ void nat64_show_all_configs(struct net *
|
|
void nat46_netdev_count_xmit(struct sk_buff *skb, struct net_device *dev);
|
|
void *netdev_nat46_instance(struct net_device *dev);
|
|
|
|
+void nat46_update_stats(struct net_device *dev, uint32_t rx_packets, uint32_t rx_bytes, uint32_t tx_packets, uint32_t tx_bytes,
|
|
+ uint32_t rx_dropped, uint32_t tx_dropped);
|
|
+bool is_map_t_dev(struct net_device *dev);
|