diff options
author | Filip Tehlar <ftehlar@cisco.com> | 2016-06-22 16:00:52 +0200 |
---|---|---|
committer | Filip Tehlar <ftehlar@cisco.com> | 2016-06-22 17:18:43 +0200 |
commit | 5b7a563ff0a39b74a0f037572b7709e3c9aa5cf2 (patch) | |
tree | c96ba70f5ac3a303bb11b2204e8e7ae434878be8 | |
parent | 7511ae85b6f59455ea362adff8b0bcc591fd3240 (diff) |
Add MAC address support for LISP
Change-Id: I79e3915fa61b497e6b586babcdf093937af07b2b
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
-rw-r--r-- | vnet/test/lisp-cp/test_lisp_types.c | 92 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.c | 62 | ||||
-rw-r--r-- | vnet/vnet/lisp-cp/lisp_types.h | 30 |
3 files changed, 166 insertions, 18 deletions
diff --git a/vnet/test/lisp-cp/test_lisp_types.c b/vnet/test/lisp-cp/test_lisp_types.c index b846cf64ca4..5d4e2a80c60 100644 --- a/vnet/test/lisp-cp/test_lisp_types.c +++ b/vnet/test/lisp-cp/test_lisp_types.c @@ -105,6 +105,28 @@ done: return error; } +static clib_error_t * test_gid_parse_mac () +{ + clib_error_t * error = 0; + gid_address_t _gid, * gid = &_gid; + gid_address_t _gid_copy, * gid_copy = &_gid_copy; + + u8 data[] = + { + 0x00, 0x06, /* AFI = MAC address */ + 0x10, 0xbb, 0xcc, 0xdd, /* MAC */ + 0x77, 0x99, + }; + + u32 len = gid_address_parse (data, gid); + _assert (8 == len); + _assert (GID_ADDR_MAC == gid_address_type (gid)); + gid_address_copy (gid_copy, gid); + _assert (0 == gid_address_cmp (gid_copy, gid)); +done: + return error; +} + static clib_error_t * test_gid_parse_lcaf () { clib_error_t * error = 0; @@ -294,6 +316,74 @@ done: return error; } +#if 0 /* uncomment this once VNI is supported */ +static clib_error_t * test_write_mac_in_lcaf (void) +{ + clib_error_t * error = 0; + + u8 * b = clib_mem_alloc(500); + memset(b, 0, 500); + + gid_address_t g = + { + .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6}, + .vni = 0x30, + .vni_mask = 0x10, + .type = GID_ADDR_MAC, + }; + + u16 len = gid_address_put (b, &g); + _assert (8 == len); + + u8 expected[] = + { + 0x40, 0x03, /* AFI = LCAF */ + 0x00, /* reserved1 */ + 0x00, /* flags */ + 0x02, /* LCAF type = Instance ID */ + 0x20, /* IID/VNI mask len */ + 0x00, 0x0a, /* length */ + 0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */ + + 0x00, 0x06, /* AFI = MAC */ + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06 /* MAC */ + } + _assert (0 == memcmp (expected, b, len)); +done: + clib_mem_free (b); + return error; +} +#endif + +static clib_error_t * test_mac_address_write (void) +{ + clib_error_t * error = 0; + + u8 * b = clib_mem_alloc(500); + memset(b, 0, 500); + + gid_address_t g = + { + .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6}, + .type = GID_ADDR_MAC, + }; + + u16 len = gid_address_put (b, &g); + _assert (8 == len); + + u8 expected[] = + { + 0x00, 0x06, /* AFI = MAC */ + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06 /* MAC */ + }; + _assert (0 == memcmp (expected, b, len)); +done: + clib_mem_free (b); + return error; +} + static clib_error_t * test_gid_address_write (void) { clib_error_t * error = 0; @@ -356,8 +446,10 @@ done: _(format_unformat_gid_address) \ _(locator_type) \ _(gid_parse_ip_pref) \ + _(gid_parse_mac) \ _(gid_parse_lcaf) \ _(gid_parse_lcaf_complex) \ + _(mac_address_write) \ _(gid_address_write) int run_tests (void) diff --git a/vnet/vnet/lisp-cp/lisp_types.c b/vnet/vnet/lisp-cp/lisp_types.c index 7a41c866b9c..9e1cb1f69e0 100644 --- a/vnet/vnet/lisp-cp/lisp_types.c +++ b/vnet/vnet/lisp-cp/lisp_types.c @@ -40,15 +40,15 @@ u16 no_addr_length (void * a); int no_addr_cmp (void * a1, void * a2); size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] = - { ip_prefix_size_to_write, lcaf_size_to_write }; + { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write }; serdes_fct write_fcts[GID_ADDR_TYPES] = - { ip_prefix_write, lcaf_write }; + { ip_prefix_write, lcaf_write, mac_write }; cast_fct cast_fcts[GID_ADDR_TYPES] = - { ip_prefix_cast, lcaf_cast }; + { ip_prefix_cast, lcaf_cast, mac_cast }; addr_len_fct addr_len_fcts[GID_ADDR_TYPES] = - { ip_prefix_length, lcaf_prefix_length }; + { ip_prefix_length, lcaf_length, mac_length }; copy_fct copy_fcts[GID_ADDR_TYPES] = - { ip_prefix_copy, lcaf_copy }; + { ip_prefix_copy, lcaf_copy, mac_copy }; cmp_fct lcaf_cmp_fcts[LCAF_TYPES] = { @@ -475,6 +475,12 @@ ip_prefix_copy (void * dst , void * src) clib_memcpy (dst, src, sizeof (ip_prefix_t)); } +void +mac_copy (void * dst , void * src) +{ + clib_memcpy (dst, src, 6); +} + int ip_prefix_cmp(ip_prefix_t * p1, ip_prefix_t * p2) { @@ -523,7 +529,13 @@ lcaf_copy (void * dst , void * src) } u8 -lcaf_prefix_length (void *a) +lcaf_length (void *a) +{ + return 0; +} + +u8 +mac_length (void *a) { return 0; } @@ -534,6 +546,12 @@ lcaf_cast (gid_address_t * a) return &gid_address_lcaf (a); } +void * +mac_cast (gid_address_t * a) +{ + return &gid_address_mac (a); +} + u16 no_addr_length (void * a) { @@ -577,6 +595,14 @@ lcaf_write (u8 * p, void * a) } u16 +mac_write (u8 * p, void * a) +{ + *(u16 *)p = clib_host_to_net_u16 (LISP_AFI_MAC); + clib_memcpy(p + sizeof (u16), a, 6); + return mac_size_to_write (a); +} + +u16 vni_write (u8 * p, void * a) { vni_t * v = a; @@ -632,6 +658,12 @@ lcaf_size_to_write (void * a) return size + len; } +u16 +mac_size_to_write (void * a) +{ + return sizeof (u16) + 6; +} + u8 gid_address_len (gid_address_t *a) { @@ -668,6 +700,16 @@ gid_address_copy(gid_address_t * dst, gid_address_t * src) } u32 +mac_parse (u8 * offset, gid_address_t * a) +{ + /* skip AFI field */ + offset += sizeof (u16); + + memcpy (gid_address_mac (a), offset, sizeof (gid_address_mac (a))); + return (sizeof (u16) + sizeof (gid_address_mac (a))); +} + +u32 gid_address_parse (u8 * offset, gid_address_t *a) { lisp_afi_e afi; @@ -700,6 +742,10 @@ gid_address_parse (u8 * offset, gid_address_t *a) len = lcaf_parse (offset, a); gid_address_type(a) = GID_ADDR_LCAF; break; + case LISP_AFI_MAC: + len = mac_parse (offset, a); + gid_address_type(a) = GID_ADDR_MAC; + break; default: clib_warning("LISP AFI %d not supported!", afi); return ~0; @@ -760,6 +806,10 @@ gid_address_cmp (gid_address_t * a1, gid_address_t * a2) if (lcaf_type (lcaf1) == lcaf_type (lcaf2)) cmp = (*lcaf_cmp_fcts[lcaf_type (lcaf1)])(lcaf1, lcaf2); break; + case GID_ADDR_MAC: + cmp = memcmp (gid_address_mac (a1), gid_address_mac (a2), + sizeof (gid_address_mac (a1))); + break; default: break; } diff --git a/vnet/vnet/lisp-cp/lisp_types.h b/vnet/vnet/lisp-cp/lisp_types.h index c4e84e165c6..b80ba0b844f 100644 --- a/vnet/vnet/lisp-cp/lisp_types.h +++ b/vnet/vnet/lisp-cp/lisp_types.h @@ -63,6 +63,7 @@ typedef enum * instead */ GID_ADDR_IP_PREFIX, GID_ADDR_LCAF, + GID_ADDR_MAC, GID_ADDR_NO_ADDRESS, GID_ADDR_TYPES } gid_address_type_t; @@ -120,6 +121,7 @@ typedef struct _gid_address_t { ip_prefix_t ippref; lcaf_t lcaf; + u8 mac[6]; }; u8 type; } gid_address_t; @@ -144,6 +146,7 @@ typedef enum { LISP_AFI_NO_ADDR, LISP_AFI_IP, LISP_AFI_IP6, + LISP_AFI_MAC = 6, LISP_AFI_LCAF = 16387 } lisp_afi_e; @@ -165,6 +168,7 @@ u32 gid_address_parse (u8 * offset, gid_address_t *a); #define gid_address_ip(_a) ip_prefix_addr(&gid_address_ippref(_a)) #define gid_address_ip_version(_a) ip_addr_version(&gid_address_ip(_a)) #define gid_address_lcaf(_a) (_a)->lcaf +#define gid_address_mac(_a) (_a)->mac #define gid_address_vni(_a) ( (GID_ADDR_LCAF == gid_address_type(_a)) ? \ lcaf_vni(&gid_address_lcaf(_a)) : 0) /* setter for vni */ @@ -172,18 +176,20 @@ u32 gid_address_parse (u8 * offset, gid_address_t *a); (lcaf_vni(&gid_address_lcaf(_a)) = (_val)) /* 'sub'address functions */ -u16 ip_prefix_size_to_write (void * pref); -u16 ip_prefix_write (u8 * p, void * pref); -u8 ip_prefix_length (void *a); -void *ip_prefix_cast (gid_address_t * a); -void ip_prefix_copy (void * dst , void * src); - -int lcaf_cmp (lcaf_t * lcaf1, lcaf_t * lcaf2); -u16 lcaf_size_to_write (void * pref); -u16 lcaf_write (u8 * p, void * pref); -u8 lcaf_prefix_length (void *a); -void *lcaf_cast (gid_address_t * a); -void lcaf_copy (void * dst , void * src); +#define foreach_gid_address_type_fcns \ + _(ip_prefix) \ + _(lcaf) \ + _(mac) + +#define _(_n) \ +u16 _n ## _size_to_write (void * pref); \ +u16 _n ## _write (u8 * p, void * pref); \ +u8 _n ## _length (void *a); \ +void * _n ## _cast (gid_address_t * a); \ +void _n ## _copy (void * dst , void * src); + +foreach_gid_address_type_fcns +#undef _ typedef struct { |