diff options
author | Neale Ranns <nranns@cisco.com> | 2018-06-07 23:48:20 -0700 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2018-07-09 21:10:53 +0000 |
commit | 947ea6222dad1ef04595c34273e9231395aef443 (patch) | |
tree | 8990854b2901ff8cc2241b9abfc99b0b4b54d517 /src/vnet/ip/igmp_packet.h | |
parent | dd47ecadcf63772a6037a1bb3715772d80e87f51 (diff) |
IGMP improvements
- Enable/Disable an interface for IGMP
- improve logging
- refactor common code
- no orphaned timers
- IGMP state changes in main thread only
- Large groups split over multiple state-change reports
- SSM range configuration API.
- more tests
Change-Id: If5674f1044e7e97274a711f47807c9ba689d7b9a
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ip/igmp_packet.h')
-rw-r--r-- | src/vnet/ip/igmp_packet.h | 88 |
1 files changed, 71 insertions, 17 deletions
diff --git a/src/vnet/ip/igmp_packet.h b/src/vnet/ip/igmp_packet.h index a8e9db6d9ab..cd4a40d77ff 100644 --- a/src/vnet/ip/igmp_packet.h +++ b/src/vnet/ip/igmp_packet.h @@ -63,32 +63,46 @@ typedef enum #define _(n,f) IGMP_TYPE_##f = n, foreach_igmp_type #undef _ -} igmp_type_t; +} __attribute__ ((packed)) igmp_type_t; typedef struct { - igmp_type_t type:8; + igmp_type_t type; u8 code; u16 checksum; } igmp_header_t; -typedef struct +/** + * Calculate the maximum response time allowed from the header. + * - RFC 3367 Section 4.1.1 + */ +always_inline f64 +igmp_header_get_max_resp_time (const igmp_header_t * header) { - /* membership_query, version <= 2 reports. */ - igmp_header_t header; + f64 qqi; - /* Multicast destination address. */ - ip4_address_t dst; -} igmp_message_t; + if (header->code < 128) + qqi = header->code; + else + { + u8 mant = header->code << 4; + u8 exp = (header->code & 0x7) << 1; + + qqi = ((mant | 0x10) << (exp + 3)); + } + + /* Querier's Query Interval (QQI), is represented in units of seconds */ + return (qqi / 10); +} typedef struct { /* type 0x11 (IGMPv3) */ igmp_header_t header; - ip4_address_t dst; + ip4_address_t group_address; /* Reserved, Suppress Router-Side Processing flag and Querier's Robustness Variable RRRRSQQQ. */ @@ -101,11 +115,25 @@ typedef struct ip4_address_t src_addresses[0]; } igmp_membership_query_v3_t; +always_inline u32 +igmp_membership_query_v3_length (const igmp_membership_query_v3_t * q) +{ + return (sizeof (*q) + + (sizeof (ip4_address_t) * + clib_net_to_host_u16 (q->n_src_addresses))); +} + +always_inline int +igmp_membership_query_v3_is_geeral (const igmp_membership_query_v3_t * q) +{ + return (0 == q->group_address.as_u32); +} + #define foreach_igmp_membership_group_v3_type \ - _ (1, mode_is_filter_include) \ - _ (2, mode_is_filter_exclude) \ - _ (3, change_to_filter_include) \ - _ (4, change_to_filter_exclude) \ + _ (1, mode_is_include) \ + _ (2, mode_is_exclude) \ + _ (3, change_to_include) \ + _ (4, change_to_exclude) \ _ (5, allow_new_sources) \ _ (6, block_old_sources) @@ -114,11 +142,11 @@ typedef enum #define _(n,f) IGMP_MEMBERSHIP_GROUP_##f = n, foreach_igmp_membership_group_v3_type #undef _ -} igmp_membership_group_v3_type_t; +} __attribute__ ((packed)) igmp_membership_group_v3_type_t; typedef struct { - igmp_membership_group_v3_type_t type:8; + igmp_membership_group_v3_type_t type; /* Number of 32 bit words of aux data after source addresses. */ u8 n_aux_u32s; @@ -126,12 +154,20 @@ typedef struct /* Number of source addresses that follow. */ u16 n_src_addresses; - /* Destination multicast address. */ - ip4_address_t dst_address; + /* Destination multicast group address. */ + ip4_address_t group_address; ip4_address_t src_addresses[0]; } igmp_membership_group_v3_t; +always_inline u32 +igmp_membership_group_v3_length (const igmp_membership_group_v3_t * g) +{ + return (sizeof (*g) + + (sizeof (ip4_address_t) * + clib_net_to_host_u16 (g->n_src_addresses))); +} + always_inline igmp_membership_group_v3_t * igmp_membership_group_v3_next (igmp_membership_group_v3_t * g) { @@ -153,6 +189,24 @@ typedef struct igmp_membership_group_v3_t groups[0]; } igmp_membership_report_v3_t; +always_inline u32 +igmp_membership_report_v3_length (const igmp_membership_report_v3_t * r) +{ + const igmp_membership_group_v3_t *g; + u32 len, ii, glen; + + len = sizeof (igmp_membership_report_v3_t); + g = r->groups; + + for (ii = 0; ii < clib_net_to_host_u16 (r->n_groups); ii++) + { + glen = igmp_membership_group_v3_length (g); + g = (const igmp_membership_group_v3_t *) (((u8 *) g) + glen); + len += glen; + } + return (len); +} + /* IP6 flavor of IGMP is called MLD which is embedded in ICMP6. */ typedef struct { |