map: use ip6-full-reassembly instead of own code
Remove map's implementation of reassembly and use common ip6-full-reassembly functionality. This makes it easier to maintain by removing duplicate code/functionality. Type: refactor Change-Id: I430e888b704e28c100a9ce075d1460cb529e4676 Signed-off-by: Klement Sekera <ksekera@cisco.com>
This commit is contained in:

committed by
Ole Trøan

parent
d5262831a3
commit
7b2e9fb1a8
File diff suppressed because it is too large
Load Diff
@ -241,28 +241,6 @@ autoreply define map_param_add_del_pre_resolve
|
||||
vl_api_ip6_address_t ip6_nh_address;
|
||||
};
|
||||
|
||||
|
||||
/** \brief Set MAP reassembly parameters
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param is_ip6 - 1 = params apply to IPv6, 0 = params apply to IPv4
|
||||
@param lifetime_ms - reassembly valid lifetime, or ~0
|
||||
@param pool_size - max number of reassemblies, or ~0
|
||||
@param buffers - max number of reassembly buffers, or ~0
|
||||
@param ht_ratio - hash-table size factor, or ~0
|
||||
*/
|
||||
autoreply define map_param_set_reassembly
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
bool is_ip6;
|
||||
u16 lifetime_ms;
|
||||
u16 pool_size;
|
||||
u32 buffers;
|
||||
f64 ht_ratio;
|
||||
};
|
||||
|
||||
|
||||
/** \brief Set MAP security-check parameters
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@ -326,10 +304,6 @@ define map_param_get
|
||||
@param icmp6_enable_unreachable - 1 = send ICMP unreachable err msgs
|
||||
@param ip4_nh_address - direct IP4 next-hop address
|
||||
@param ip6_nh_address - direct IP6 next-hop address
|
||||
@param ip6_lifetime_ms - max number of reassemblies, or ~0
|
||||
@param ip6_pool_size - max number of reassemblies, or ~0
|
||||
@param ip6_buffers - max number of reassembly buffers, or ~0
|
||||
@param ip6_ht_ratio - hash-table size factor, or ~0
|
||||
@param sec_check_enable - 1=enable security check on first inbound packet
|
||||
@param sec_check_fragments - 1=enable check on (subsequent) fragments too
|
||||
@param tc_copy - 1 = copy packet class/TOS field, 0 = use class instead
|
||||
@ -349,10 +323,6 @@ define map_param_get_reply
|
||||
u16 ip4_pool_size;
|
||||
u32 ip4_buffers;
|
||||
f64 ip4_ht_ratio;
|
||||
u16 ip6_lifetime_ms;
|
||||
u16 ip6_pool_size;
|
||||
u32 ip6_buffers;
|
||||
f64 ip6_ht_ratio;
|
||||
bool sec_check_enable;
|
||||
bool sec_check_fragments;
|
||||
bool tc_copy;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,9 +50,6 @@ int map_param_set_fragmentation (bool inner, bool ignore_df);
|
||||
int map_param_set_icmp (ip4_address_t * ip4_err_relay_src);
|
||||
int map_param_set_icmp6 (u8 enable_unreachable);
|
||||
void map_pre_resolve (ip4_address_t * ip4, ip6_address_t * ip6, bool is_del);
|
||||
int map_param_set_reassembly (bool is_ipv6, u16 lifetime_ms, u16 pool_size,
|
||||
u32 buffers, f64 ht_ratio, u32 * reass,
|
||||
u32 * packets);
|
||||
int map_param_set_security_check (bool enable, bool fragments);
|
||||
int map_param_set_traffic_class (bool copy, u8 tc);
|
||||
int map_param_set_tcp (u16 tcp_mss);
|
||||
@ -65,15 +62,6 @@ typedef enum
|
||||
MAP_DOMAIN_RFC6052 = 1 << 2,
|
||||
} __attribute__ ((__packed__)) map_domain_flags_e;
|
||||
|
||||
#define MAP_IP6_REASS_LIFETIME_DEFAULT (100) /* ms */
|
||||
#define MAP_IP6_REASS_HT_RATIO_DEFAULT (1.0)
|
||||
#define MAP_IP6_REASS_POOL_SIZE_DEFAULT 1024 // Number of reassembly structures
|
||||
#define MAP_IP6_REASS_BUFFERS_DEFAULT 2048
|
||||
|
||||
#define MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY 5
|
||||
|
||||
#define MAP_IP6_REASS_COUNT_BYTES
|
||||
|
||||
//#define IP6_MAP_T_OVERRIDE_TOS 0
|
||||
|
||||
/*
|
||||
@ -136,46 +124,6 @@ typedef enum
|
||||
MAP_N_DOMAIN_COUNTER
|
||||
} map_domain_counter_t;
|
||||
|
||||
/*
|
||||
* main_main_t
|
||||
*/
|
||||
/* *INDENT-OFF* */
|
||||
typedef union {
|
||||
CLIB_PACKED (struct {
|
||||
ip6_address_t src;
|
||||
ip6_address_t dst;
|
||||
u32 fragment_id;
|
||||
u8 protocol;
|
||||
});
|
||||
u64 as_u64[5];
|
||||
u32 as_u32[10];
|
||||
} map_ip6_reass_key_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 pi; //Cached packet or ~0
|
||||
u16 next_data_offset; //The data offset of the additional 20 bytes or ~0
|
||||
u8 next_data_len; //Number of bytes ready to be copied (20 if not last fragment)
|
||||
u8 next_data[20]; //The 20 additional bytes
|
||||
} map_ip6_fragment_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
map_ip6_reass_key_t key;
|
||||
f64 ts;
|
||||
#ifdef MAP_IP6_REASS_COUNT_BYTES
|
||||
u16 expected_total;
|
||||
u16 forwarded;
|
||||
#endif
|
||||
u16 bucket; //What hash bucket this element is linked in
|
||||
u16 bucket_next;
|
||||
u16 fifo_prev;
|
||||
u16 fifo_next;
|
||||
ip4_header_t ip4_header;
|
||||
map_ip6_fragment_t fragments[MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY];
|
||||
} map_ip6_reass_t;
|
||||
|
||||
#ifdef MAP_SKIP_IP6_LOOKUP
|
||||
/**
|
||||
* A pre-resolved next-hop
|
||||
@ -245,26 +193,6 @@ typedef struct
|
||||
bool frag_inner; /* Inner or outer fragmentation */
|
||||
bool frag_ignore_df; /* Fragment (outer) packet even if DF is set */
|
||||
|
||||
/*
|
||||
* IPv6 decap reassembly
|
||||
*/
|
||||
/* Configuration */
|
||||
f32 ip6_reass_conf_ht_ratio; //Size of ht is 2^ceil(log2(ratio*pool_size))
|
||||
u16 ip6_reass_conf_pool_size; //Max number of allocated reass structures
|
||||
u16 ip6_reass_conf_lifetime_ms; //Time a reassembly struct is considered valid in ms
|
||||
u32 ip6_reass_conf_buffers; //Maximum number of buffers used by ip6 reassembly
|
||||
|
||||
/* Runtime */
|
||||
map_ip6_reass_t *ip6_reass_pool;
|
||||
u8 ip6_reass_ht_log2len; //Hash table size is 2^log2len
|
||||
u16 ip6_reass_allocated;
|
||||
u16 *ip6_reass_hash_table;
|
||||
u16 ip6_reass_fifo_last;
|
||||
clib_spinlock_t ip6_reass_lock;
|
||||
|
||||
/* Counters */
|
||||
u32 ip6_reass_buffered_counter;
|
||||
|
||||
/* Graph node state */
|
||||
uword *bm_trans_enabled_by_sw_if;
|
||||
uword *bm_encap_enabled_by_sw_if;
|
||||
@ -445,35 +373,8 @@ ip6_map_get_domain (ip6_address_t * addr, u32 * map_domain_index, u8 * error)
|
||||
|
||||
clib_error_t *map_plugin_api_hookup (vlib_main_t * vm);
|
||||
|
||||
map_ip6_reass_t *map_ip6_reass_get (ip6_address_t * src, ip6_address_t * dst,
|
||||
u32 fragment_id, u8 protocol,
|
||||
u32 ** pi_to_drop);
|
||||
void map_ip6_reass_free (map_ip6_reass_t * r, u32 ** pi_to_drop);
|
||||
|
||||
#define map_ip6_reass_lock() clib_spinlock_lock (&map_main.ip6_reass_lock)
|
||||
#define map_ip6_reass_unlock() clib_spinlock_unlock (&map_main.ip6_reass_lock)
|
||||
|
||||
int
|
||||
map_ip6_reass_add_fragment (map_ip6_reass_t * r, u32 pi,
|
||||
u16 data_offset, u16 next_data_offset,
|
||||
u8 * data_start, u16 data_len);
|
||||
|
||||
void map_ip4_drop_pi (u32 pi);
|
||||
|
||||
void map_ip6_drop_pi (u32 pi);
|
||||
|
||||
|
||||
int map_ip6_reass_conf_ht_ratio (f32 ht_ratio, u32 * trashed_reass,
|
||||
u32 * dropped_packets);
|
||||
#define MAP_IP6_REASS_CONF_HT_RATIO_MAX 100
|
||||
int map_ip6_reass_conf_pool_size (u16 pool_size, u32 * trashed_reass,
|
||||
u32 * dropped_packets);
|
||||
#define MAP_IP6_REASS_CONF_POOL_SIZE_MAX (0xfeff)
|
||||
int map_ip6_reass_conf_lifetime (u16 lifetime_ms);
|
||||
#define MAP_IP6_REASS_CONF_LIFETIME_MAX 0xffff
|
||||
int map_ip6_reass_conf_buffers (u32 buffers);
|
||||
#define MAP_IP6_REASS_CONF_BUFFERS_MAX (0xffffffff)
|
||||
|
||||
/*
|
||||
* Supports prefix of 96 or 64 (with u-octet)
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <vnet/ip/ip.h>
|
||||
#include <vnet/ip/reass/ip4_sv_reass.h>
|
||||
#include <vnet/ip/reass/ip6_sv_reass.h>
|
||||
#include <vnet/ip/reass/ip6_full_reass.h>
|
||||
#include <vnet/fib/fib_table.h>
|
||||
#include <vlibmemory/api.h>
|
||||
|
||||
@ -330,102 +331,6 @@ static void
|
||||
REPLY_MACRO (VL_API_MAP_PARAM_ADD_DEL_PRE_RESOLVE_REPLY);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
map_param_set_reassembly (bool is_ipv6,
|
||||
u16 lifetime_ms,
|
||||
u16 pool_size,
|
||||
u32 buffers,
|
||||
f64 ht_ratio, u32 * reass, u32 * packets)
|
||||
{
|
||||
u32 ps_reass = 0, ps_packets = 0;
|
||||
u32 ht_reass = 0, ht_packets = 0;
|
||||
|
||||
if (is_ipv6)
|
||||
{
|
||||
if (pool_size != (u16) ~ 0)
|
||||
{
|
||||
if (pool_size > MAP_IP6_REASS_CONF_POOL_SIZE_MAX)
|
||||
return MAP_ERR_BAD_POOL_SIZE;
|
||||
if (map_ip6_reass_conf_pool_size
|
||||
(pool_size, &ps_reass, &ps_packets))
|
||||
return MAP_ERR_BAD_POOL_SIZE;
|
||||
}
|
||||
|
||||
if (ht_ratio != (MAP_IP6_REASS_CONF_HT_RATIO_MAX + 1))
|
||||
{
|
||||
if (ht_ratio > MAP_IP6_REASS_CONF_HT_RATIO_MAX)
|
||||
return MAP_ERR_BAD_HT_RATIO;
|
||||
if (map_ip6_reass_conf_ht_ratio (ht_ratio, &ht_reass, &ht_packets))
|
||||
return MAP_ERR_BAD_HT_RATIO;
|
||||
}
|
||||
|
||||
if (lifetime_ms != (u16) ~ 0)
|
||||
{
|
||||
if (lifetime_ms > MAP_IP6_REASS_CONF_LIFETIME_MAX)
|
||||
return MAP_ERR_BAD_LIFETIME;
|
||||
if (map_ip6_reass_conf_lifetime (lifetime_ms))
|
||||
return MAP_ERR_BAD_LIFETIME;
|
||||
}
|
||||
|
||||
if (buffers != ~0)
|
||||
{
|
||||
if (buffers > MAP_IP6_REASS_CONF_BUFFERS_MAX)
|
||||
return MAP_ERR_BAD_BUFFERS;
|
||||
if (map_ip6_reass_conf_buffers (buffers))
|
||||
return MAP_ERR_BAD_BUFFERS;
|
||||
}
|
||||
|
||||
if (map_main.ip6_reass_conf_buffers >
|
||||
map_main.ip6_reass_conf_pool_size *
|
||||
MAP_IP6_REASS_MAX_FRAGMENTS_PER_REASSEMBLY)
|
||||
{
|
||||
return MAP_ERR_BAD_BUFFERS_TOO_LARGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return MAP_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (reass)
|
||||
*reass = ps_reass + ht_reass;
|
||||
|
||||
if (packets)
|
||||
*packets = ps_packets + ht_packets;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vl_api_map_param_set_reassembly_t_handler
|
||||
(vl_api_map_param_set_reassembly_t * mp)
|
||||
{
|
||||
map_main_t *mm = &map_main;
|
||||
vl_api_map_param_set_reassembly_reply_t *rmp;
|
||||
u32 reass = 0, packets = 0;
|
||||
int rv;
|
||||
f64 ht_ratio;
|
||||
|
||||
ht_ratio = (f64) clib_net_to_host_f64 (mp->ht_ratio);
|
||||
if (ht_ratio == ~0)
|
||||
ht_ratio = MAP_IP6_REASS_CONF_HT_RATIO_MAX + 1;
|
||||
|
||||
rv = map_param_set_reassembly (mp->is_ip6,
|
||||
clib_net_to_host_u16 (mp->lifetime_ms),
|
||||
clib_net_to_host_u16 (mp->pool_size),
|
||||
clib_net_to_host_u32 (mp->buffers),
|
||||
ht_ratio, &reass, &packets);
|
||||
|
||||
/*
|
||||
* FIXME: Should the lost reass and packet counts be returned in the API?
|
||||
*/
|
||||
|
||||
REPLY_MACRO (VL_API_MAP_PARAM_SET_REASSEMBLY_REPLY);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
map_param_set_security_check (bool enable, bool fragments)
|
||||
{
|
||||
@ -530,12 +435,6 @@ vl_api_map_param_get_t_handler (vl_api_map_param_get_t * mp)
|
||||
clib_memset (&rmp->ip4_nh_address, 0, sizeof (rmp->ip4_nh_address));
|
||||
clib_memset (&rmp->ip6_nh_address, 0, sizeof (rmp->ip6_nh_address));
|
||||
|
||||
rmp->ip6_lifetime_ms =
|
||||
clib_net_to_host_u16 (mm->ip6_reass_conf_lifetime_ms);
|
||||
rmp->ip6_pool_size = clib_net_to_host_u16 (mm->ip6_reass_conf_pool_size);
|
||||
rmp->ip6_buffers = clib_net_to_host_u32 (mm->ip6_reass_conf_buffers);
|
||||
rmp->ip6_ht_ratio = clib_net_to_host_f64 (mm->ip6_reass_conf_ht_ratio);
|
||||
|
||||
rmp->sec_check_enable = mm->sec_check;
|
||||
rmp->sec_check_fragments = mm->sec_check_frag;
|
||||
|
||||
@ -573,6 +472,7 @@ map_if_enable_disable (bool is_enable, u32 sw_if_index, bool is_translation)
|
||||
if (is_translation == false)
|
||||
{
|
||||
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, is_enable);
|
||||
ip6_full_reass_enable_disable_with_refcnt (sw_if_index, is_enable);
|
||||
vnet_feature_enable_disable ("ip4-unicast", "ip4-map", sw_if_index,
|
||||
is_enable ? 1 : 0, 0, 0);
|
||||
vnet_feature_enable_disable ("ip6-unicast", "ip6-map", sw_if_index,
|
||||
|
@ -7,7 +7,7 @@ from ipaddress import IPv6Network, IPv4Network
|
||||
from framework import VppTestCase, VppTestRunner
|
||||
from vpp_ip import DpoProto
|
||||
from vpp_ip_route import VppIpRoute, VppRoutePath
|
||||
from util import fragment_rfc791
|
||||
from util import fragment_rfc791, fragment_rfc8200
|
||||
|
||||
import scapy.compat
|
||||
from scapy.layers.l2 import Ether, Raw
|
||||
@ -227,6 +227,29 @@ class TestMAP(VppTestCase):
|
||||
|
||||
rx = self.pg0.get_capture(len(frags))
|
||||
|
||||
for r in rx:
|
||||
self.assertFalse(r.haslayer(IPv6))
|
||||
self.assertEqual(r[IP].src, p[IP].src)
|
||||
self.assertEqual(r[IP].dst, p[IP].dst)
|
||||
|
||||
# Verify that fragments pass even if ipv6 layer is fragmented
|
||||
stream = (IPv6(dst='3000::1', src=map_translated_addr) / x
|
||||
for x in frags)
|
||||
|
||||
v6_stream = [
|
||||
Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / x
|
||||
for i in range(len(frags))
|
||||
for x in fragment_rfc8200(
|
||||
IPv6(dst='3000::1', src=map_translated_addr) / frags[i],
|
||||
i, 200)]
|
||||
|
||||
self.pg1.add_stream(v6_stream)
|
||||
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
|
||||
rx = self.pg0.get_capture(len(frags))
|
||||
|
||||
for r in rx:
|
||||
self.assertFalse(r.haslayer(IPv6))
|
||||
self.assertEqual(r[IP].src, p[IP].src)
|
||||
|
@ -185,6 +185,8 @@ typedef struct
|
||||
u32 fq_index;
|
||||
u32 fq_feature_index;
|
||||
|
||||
// reference count for enabling/disabling feature - per interface
|
||||
u32 *feature_use_refcount_per_intf;
|
||||
} ip4_full_reass_main_t;
|
||||
|
||||
extern ip4_full_reass_main_t ip4_full_reass_main;
|
||||
@ -1448,6 +1450,7 @@ ip4_full_reass_init_function (vlib_main_t * vm)
|
||||
rm->fq_feature_index =
|
||||
vlib_frame_queue_main_init (ip4_full_reass_node_feature.index, 0);
|
||||
|
||||
rm->feature_use_refcount_per_intf = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1793,6 +1796,35 @@ VLIB_REGISTER_NODE (ip4_full_reass_feature_handoff_node) = {
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#ifndef CLIB_MARCH_VARIANT
|
||||
int
|
||||
ip4_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable)
|
||||
{
|
||||
ip4_full_reass_main_t *rm = &ip4_full_reass_main;
|
||||
vec_validate (rm->feature_use_refcount_per_intf, sw_if_index);
|
||||
if (is_enable)
|
||||
{
|
||||
if (!rm->feature_use_refcount_per_intf[sw_if_index])
|
||||
{
|
||||
++rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
return vnet_feature_enable_disable ("ip4-unicast",
|
||||
"ip4-full-reassembly-feature",
|
||||
sw_if_index, 1, 0, 0);
|
||||
}
|
||||
++rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
--rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
if (!rm->feature_use_refcount_per_intf[sw_if_index])
|
||||
return vnet_feature_enable_disable ("ip4-unicast",
|
||||
"ip4-full-reassembly-feature",
|
||||
sw_if_index, 0, 0, 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
|
@ -43,6 +43,9 @@ vnet_api_error_t ip4_full_reass_get (u32 * timeout_ms, u32 * max_reassemblies,
|
||||
vnet_api_error_t ip4_full_reass_enable_disable (u32 sw_if_index,
|
||||
u8 enable_disable);
|
||||
|
||||
int ip4_full_reass_enable_disable_with_refcnt (u32 sw_if_index,
|
||||
int is_enable);
|
||||
|
||||
#endif /* __included_ip4_full_reass_h__ */
|
||||
|
||||
/*
|
||||
|
@ -164,6 +164,8 @@ typedef struct
|
||||
u32 fq_index;
|
||||
u32 fq_feature_index;
|
||||
|
||||
// reference count for enabling/disabling feature - per interface
|
||||
u32 *feature_use_refcount_per_intf;
|
||||
} ip6_full_reass_main_t;
|
||||
|
||||
extern ip6_full_reass_main_t ip6_full_reass_main;
|
||||
@ -1427,6 +1429,7 @@ ip6_full_reass_init_function (vlib_main_t * vm)
|
||||
rm->fq_feature_index =
|
||||
vlib_frame_queue_main_init (ip6_full_reass_node_feature.index, 0);
|
||||
|
||||
rm->feature_use_refcount_per_intf = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1790,6 +1793,35 @@ VLIB_REGISTER_NODE (ip6_full_reassembly_feature_handoff_node) = {
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#ifndef CLIB_MARCH_VARIANT
|
||||
int
|
||||
ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable)
|
||||
{
|
||||
ip6_full_reass_main_t *rm = &ip6_full_reass_main;
|
||||
vec_validate (rm->feature_use_refcount_per_intf, sw_if_index);
|
||||
if (is_enable)
|
||||
{
|
||||
if (!rm->feature_use_refcount_per_intf[sw_if_index])
|
||||
{
|
||||
++rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
return vnet_feature_enable_disable ("ip6-unicast",
|
||||
"ip6-full-reassembly-feature",
|
||||
sw_if_index, 1, 0, 0);
|
||||
}
|
||||
++rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
--rm->feature_use_refcount_per_intf[sw_if_index];
|
||||
if (!rm->feature_use_refcount_per_intf[sw_if_index])
|
||||
return vnet_feature_enable_disable ("ip6-unicast",
|
||||
"ip6-full-reassembly-feature",
|
||||
sw_if_index, 0, 0, 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
|
@ -43,6 +43,9 @@ vnet_api_error_t ip6_full_reass_get (u32 * timeout_ms, u32 * max_reassemblies,
|
||||
vnet_api_error_t ip6_full_reass_enable_disable (u32 sw_if_index,
|
||||
u8 enable_disable);
|
||||
|
||||
int ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index,
|
||||
int is_enable);
|
||||
|
||||
#endif /* __included_ip6_full_reass_h */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user