IPv6 HBH: Refactor code. Separate out RFC2460 HBH handling and the more experimental

IOAM code. Support dynamically adding options. By default
          only process HBH if explicitly configured to. Otherwise we'll just set
          ourselves up to be a victim of DOS.

Change-Id: I41cdfdc00aeaa0cf568e4463440b89be761b6b7d
Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
Ole Troan
2016-05-24 11:56:58 +02:00
committed by Dave Barach
parent 6f91cfe4aa
commit 944f548d10
8 changed files with 620 additions and 568 deletions

84
vnet/etc/scripts/ip6-hbh Normal file
View File

@ -0,0 +1,84 @@
tap connect tap0
set int state tap-0 up
set int ip address tap-0 1::1/64
packet-generator new {
name hbh1
limit 1
node ip6-input
size 48-48
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
hex 0x3B00010403040506
incrementing 100
}
}
packet-generator new {
name hbh2
limit 1
node ip6-input
size 48-48
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
hex 0x3B00C10403040506
incrementing 100
}
}
packet-generator new {
name hbh3
limit 1
node ip6-input
size 48-48
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
hex 0x3BffC10403040506
incrementing 100
}
}
packet-generator new {
name hbh4
limit 1
node ip6-input
size 64-64
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
hex 0x3BffC10403040506
incrementing 100
}
}
packet-generator new {
name hbh5
limit 1
node ip6-input
size 56-56
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
length 16
hex 0x3B010104030405060106030405060708
incrementing 100
}
}
packet-generator new {
name hbh6
limit 1
node ip6-input
size 56-56
no-recycle
data {
IP6_HOP_BY_HOP_OPTIONS: 1::2 -> 1::2
length 16
hex 0x3a00050200000100
ICMP echo_request
incrementing 100
}
}
tr add pg-input 100

View File

@ -42,8 +42,9 @@
#include <vlib/mc.h>
#include <vnet/ip/ip6_packet.h>
#include <vnet/ip/ip6_hop_by_hop_packet.h>
#include <vnet/ip/lookup.h>
#include <stdbool.h>
#include <vppinfra/bihash_24_8.h>
#include <vppinfra/bihash_template.h>
@ -176,6 +177,9 @@ typedef struct ip6_main_t {
u8 pad[3];
} host_config;
/* HBH processing enabled? */
u8 hbh_enabled;
} ip6_main_t;
/* Global ip6 main structure. */
@ -521,4 +525,23 @@ ip6_compute_flow_hash (ip6_header_t * ip, u32 flow_hash_config)
return (u32) c;
}
/*
* Hop-by-Hop handling
*/
typedef struct {
/* Array of function pointers to HBH option handling routines */
int (*options[256])(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt);
u8 *(*trace[256])(u8 *s, ip6_hop_by_hop_option_t *opt);
} ip6_hop_by_hop_main_t;
extern ip6_hop_by_hop_main_t ip6_hop_by_hop_main;
int ip6_hbh_register_option (u8 option,
int options(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt),
u8 *trace(u8 *s, ip6_hop_by_hop_option_t *opt));
int ip6_hbh_unregister_option (u8 option);
/* Flag used by IOAM code. Classifier sets it pop-hop-by-hop checks it */
#define OI_DECAP 100
#endif /* included_ip_ip6_h */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __included_ip6_hop_by_hop_h__
#define __included_ip6_hop_by_hop_h__
#ifndef __included_ip6_hop_by_hop_ioam_h__
#define __included_ip6_hop_by_hop_ioam_h__
#include <vnet/ip/ip6_hop_by_hop.h>
#include <vnet/ip/ip6_hop_by_hop_packet.h>
#include <vnet/ip/ip.h>
@ -62,9 +63,9 @@ typedef struct {
/* convenience */
vlib_main_t * vlib_main;
vnet_main_t * vnet_main;
} ip6_hop_by_hop_main_t;
} ip6_hop_by_hop_ioam_main_t;
extern ip6_hop_by_hop_main_t ip6_hop_by_hop_main;
extern ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main;
extern u8 * format_path_map(u8 * s, va_list * args);
extern clib_error_t *
@ -102,5 +103,5 @@ static inline u8 is_zero_ip6_address (ip6_address_t *a)
return ((a->as_u64[0] == 0) && (a->as_u64[1] == 0));
}
extern ip6_hop_by_hop_main_t * hm;
#endif /* __included_ip6_hop_by_hop_h__ */
extern ip6_hop_by_hop_ioam_main_t * hm;
#endif /* __included_ip6_hop_by_hop_ioam_h__ */

View File

@ -27,20 +27,20 @@ typedef struct {
typedef struct {
/* Option Type */
#define HBH_OPTION_TYPE_SKIP_UNKNOWN (0x0 << 6)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN (0x1 << 6)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN_ICMP (0x2 << 6)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN_ICMP_NOT_MCAST (0x3 << 6)
#define HBH_OPTION_TYPE_SKIP_UNKNOWN (0x00)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN (0x40)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN_ICMP (0x80)
#define HBH_OPTION_TYPE_DISCARD_UNKNOWN_ICMP_NOT_MCAST (0xc0)
#define HBH_OPTION_TYPE_HIGH_ORDER_BITS (0xc0)
#define HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE (1<<5)
#define HBH_OPTION_TYPE_MASK (0x1F)
u8 type;
/* Length in octets of the option data field */
u8 length;
} ip6_hop_by_hop_option_t;
/* $$$$ IANA banana constants */
#define HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST 27
#define HBH_OPTION_TYPE_IOAM_PROOF_OF_WORK 28
#define HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST 59 /* Third highest bit set (change en-route) */
#define HBH_OPTION_TYPE_IOAM_PROOF_OF_WORK 60 /* Third highest bit set (change en-route) */
#define HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE 29
/*

View File

@ -87,6 +87,8 @@ typedef enum {
IP_LOOKUP_NEXT_ADD_HOP_BY_HOP,
IP_LOOKUP_NEXT_POP_HOP_BY_HOP,
IP_LOOKUP_NEXT_ICMP_ERROR,
IP_LOOKUP_N_NEXT,
} ip_lookup_next_t;
@ -105,6 +107,7 @@ typedef enum {
[IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip4-add-hop-by-hop", \
[IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip4-pop-hop-by-hop", \
[IP_LOOKUP_NEXT_INDIRECT] = "ip4-indirect", \
[IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error", \
}
#define IP6_LOOKUP_NEXT_NODES { \
@ -122,6 +125,7 @@ typedef enum {
[IP_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop", \
[IP_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop", \
[IP_LOOKUP_NEXT_INDIRECT] = "ip6-indirect", \
[IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error", \
}
/* Flow hash configuration */

View File

@ -206,7 +206,7 @@ static inline u16 scv_get_next_profile_id(vlib_main_t * vm, u16 id)
}
static inline void
scv_profile_invalidate(vlib_main_t * vm, ip6_hop_by_hop_main_t * hm,
scv_profile_invalidate(vlib_main_t * vm, ip6_hop_by_hop_ioam_main_t * hm,
u16 id, u8 is_encap)
{
scv_profile *p = scv_profile_find(id);