Skip to content

Commit

Permalink
* pre_tag_map: introduced 'mpls_pw_id' keyword to match the signalled…
Browse files Browse the repository at this point in the history
… MPLS

  L2 VPNs Pseudowire ID. In NetFlow v9/IPFIX this is compared against IE
  pmacct#249; in sFlow v5 this is compared against vll_vc_id field, extended MPLS
  VC object.
  • Loading branch information
paololucente authored and paolo committed Dec 11, 2013
1 parent d41f5b5 commit 49ab777
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 5 deletions.
4 changes: 2 additions & 2 deletions CONFIG-KEYS
Original file line number Diff line number Diff line change
Expand Up @@ -957,8 +957,8 @@ DESC: enables indexing of maps to increase lookup speeds on large maps and/or s
rates. Indexes are automatically defined basing on structure and content of the map, up to
a maximum of 8. Indexing of pre_tag_map, bgp_peer_src_as_map, flows_to_rd_map is supported.
Only a sub-set of pre_tag_map fields are supported, including: ip, bgp_nexthop, vlan_id,
src_mac, mpls_vpn_rd, src_as, dst_as, peer_src_as, peer_dst_as, input, output). Only IP
addresses, ie. no IP prefixes, are supported as part of the 'ip' field. Also, negations
src_mac, mpls_vpn_rd, mpls_pw_id, src_as, dst_as, peer_src_as, peer_dst_as, input, output).
Only IP addresses, ie. no IP prefixes, are supported as part of the 'ip' field. Also, negations
are not supported (ie. 'in=-216' match all but input interface 216). bgp_agent_map and
sampling_map implement a separate caching mechanism and hence do not leverage this feature.
(default: false)
Expand Down
4 changes: 4 additions & 0 deletions examples/pretag.map.example
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@
! 'mpls_vpn_rd' MATCH: Destination IP prefix BGP-signalled MPLS L2/L3
! VPN Route Distinguisher (RD) value. Encoding types #0, #1
! and #2 are supported as per rfc4364. See example below.
! 'mpls_pw_id' MATCH: Signalled MPLS L2 VPNs Pseudowire ID. In NetFlow
! v9/IPFIX this is compared against IE #249; in sFlow v5
! this is compared against vll_vc_id field, extended MPLS
! VC object.
! 'src_mac' MATCH: In NetFlow v9 and IPFIX this is compared against
! IE #56, in sFlow against source MAC address field part
! of the Extended Switch object.
Expand Down
2 changes: 2 additions & 0 deletions src/nfacctd.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,8 @@ struct data_hdr_v9 {
#define NF9_INGRESS_VRFID 234
#define NF9_EGRESS_VRFID 235
/* ... */
#define NF9_PSEUDOWIREID 249
/* ... */
#define NF9_ETHERTYPE 256
/* ... */
#define NF9_OBSERVATION_TIME_SEC 322
Expand Down
2 changes: 1 addition & 1 deletion src/pmacct-build.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define PMACCT_BUILD "20131209-00"
#define PMACCT_BUILD "20131211-00"
3 changes: 3 additions & 0 deletions src/pretag-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const struct _map_dictionary_line tag_map_dictionary[] = {
{"src_comms", PT_map_src_comms_handler},
{"comms", PT_map_comms_handler},
{"mpls_vpn_rd", PT_map_mpls_vpn_rd_handler},
{"mpls_pw_id", PT_map_mpls_pw_id_handler},
{"src_mac", PT_map_src_mac_handler},
{"vlan", PT_map_vlan_id_handler},
{"set_tag", PT_map_id_handler},
Expand All @@ -68,6 +69,7 @@ const struct _map_index_dictionary_line tag_map_index_entries_dictionary[] = {
{PRETAG_PEER_DST_AS, PT_map_index_entries_peer_dst_as_handler},
{PRETAG_MPLS_LABEL_BOTTOM, PT_map_index_entries_mpls_label_bottom_handler},
{PRETAG_MPLS_VPN_RD, PT_map_index_entries_mpls_vpn_rd_handler},
{PRETAG_MPLS_PW_ID, PT_map_index_entries_mpls_pw_id_handler},
{PRETAG_SRC_MAC, PT_map_index_entries_src_mac_handler},
{PRETAG_VLAN_ID, PT_map_index_entries_vlan_id_handler},
{0, NULL}
Expand All @@ -84,6 +86,7 @@ const struct _map_index_dictionary_line tag_map_index_fdata_dictionary[] = {
{PRETAG_PEER_DST_AS, PT_map_index_fdata_peer_dst_as_handler},
{PRETAG_MPLS_LABEL_BOTTOM, PT_map_index_fdata_mpls_label_bottom_handler},
{PRETAG_MPLS_VPN_RD, PT_map_index_fdata_mpls_vpn_rd_handler},
{PRETAG_MPLS_PW_ID, PT_map_index_fdata_mpls_pw_id_handler},
{PRETAG_SRC_MAC, PT_map_index_fdata_src_mac_handler},
{PRETAG_VLAN_ID, PT_map_index_fdata_vlan_id_handler},
{0, NULL}
Expand Down
2 changes: 2 additions & 0 deletions src/pretag.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#define PRETAG_SRC_MAC 0x08000000
#define PRETAG_VLAN_ID 0x10000000
#define PRETAG_IP 0x20000000
#define PRETAG_MPLS_PW_ID 0x40000000

#define PRETAG_MAP_RCODE_ID 0x00000100
#define PRETAG_MAP_RCODE_ID2 0x00000200
Expand Down Expand Up @@ -157,6 +158,7 @@ struct id_entry {
char *src_comms[16]; /* XXX: MAX_BGP_COMM_PATTERNS = 16 */
char *comms[16]; /* XXX: MAX_BGP_COMM_PATTERNS = 16 */
pt_rd_t mpls_vpn_rd;
pt_uint32_t mpls_pw_id;
struct bpf_program filter;
pt_uint8_t v8agg;
pretag_handler func[N_MAP_HANDLERS];
Expand Down
85 changes: 85 additions & 0 deletions src/pretag_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,28 @@ int PT_map_mpls_vpn_rd_handler(char *filename, struct id_entry *e, char *value,
else return TRUE;
}

int PT_map_mpls_pw_id_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
{
int x = 0;
char *endptr;

e->mpls_pw_id.neg = pt_check_neg(&value, &((struct id_table *) req->key_value_table)->flags);
e->mpls_pw_id.n = strtoul(value, &endptr, 10);

for (x = 0; e->func[x]; x++) {
if (e->func_type[x] == PRETAG_MPLS_PW_ID) {
Log(LOG_ERR, "ERROR ( %s ): Multiple 'mpls_pw_id' clauses part of the same statement. ", filename);
return TRUE;
}
}

if (config.acct_type == ACCT_NF) e->func[x] = pretag_mpls_pw_id_handler;
else if (config.acct_type == ACCT_SF) e->func[x] = SF_pretag_mpls_pw_id_handler;
if (e->func[x]) e->func_type[x] = PRETAG_MPLS_PW_ID;

return FALSE;
}

int PT_map_src_mac_handler(char *filename, struct id_entry *e, char *value, struct plugin_requests *req, int acct_type)
{
int x = 0;
Expand Down Expand Up @@ -1804,6 +1826,25 @@ int pretag_mpls_vpn_rd_handler(struct packet_ptrs *pptrs, void *unused, void *e)
else return (TRUE ^ entry->mpls_vpn_rd.neg);
}

int pretag_mpls_pw_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
{
struct id_entry *entry = e;
struct struct_header_v8 *hdr = (struct struct_header_v8 *) pptrs->f_header;
struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;

switch (hdr->version) {
case 10:
case 9:
if (tpl->tpl[NF9_PSEUDOWIREID].len) {
if (!memcmp(&entry->mpls_pw_id.n, pptrs->f_data+tpl->tpl[NF9_PSEUDOWIREID].off, 4))
return (FALSE | entry->mpls_pw_id.neg);
else return (TRUE ^ entry->mpls_pw_id.neg);
}
default:
return TRUE; /* this field does not exist: condition is always true */
}
}

int pretag_src_mac_handler(struct packet_ptrs *pptrs, void *unused, void *e)
{
struct id_entry *entry = e;
Expand Down Expand Up @@ -2037,6 +2078,15 @@ int SF_pretag_vlan_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
else return (TRUE ^ entry->vlan_id.neg);
}

int SF_pretag_mpls_pw_id_handler(struct packet_ptrs *pptrs, void *unused, void *e)
{
struct id_entry *entry = e;
SFSample *sample = (SFSample *) pptrs->f_data;

if (entry->mpls_pw_id.n == sample->mpls_vll_vc_id) return (FALSE | entry->mpls_pw_id.neg);
else return (TRUE ^ entry->mpls_pw_id.neg);
}

int PM_pretag_src_as_handler(struct packet_ptrs *pptrs, void *unused, void *e)
{
struct id_entry *entry = e;
Expand Down Expand Up @@ -2501,6 +2551,17 @@ int PT_map_index_entries_mpls_vpn_rd_handler(struct id_entry *e, void *src)
return FALSE;
}

int PT_map_index_entries_mpls_pw_id_handler(struct id_entry *e, void *src)
{
struct id_entry *src_e = (struct id_entry *) src;

if (!e || !src_e) return TRUE;

memcpy(&e->mpls_pw_id, &src_e->mpls_pw_id, sizeof(pt_uint32_t));

return FALSE;
}

int PT_map_index_entries_mpls_label_bottom_handler(struct id_entry *e, void *src)
{
struct id_entry *src_e = (struct id_entry *) src;
Expand Down Expand Up @@ -2960,6 +3021,30 @@ int PT_map_index_fdata_mpls_vpn_rd_handler(struct id_entry *e, void *src)
}
}

int PT_map_index_fdata_mpls_pw_id_handler(struct id_entry *e, void *src)
{
struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
struct struct_header_v8 *hdr = (struct struct_header_v8 *) pptrs->f_header;
struct template_cache_entry *tpl = (struct template_cache_entry *) pptrs->f_tpl;
SFSample *sample = (SFSample *) pptrs->f_data;

if (config.acct_type == ACCT_NF) {
switch (hdr->version) {
case 10:
case 9:
if (tpl->tpl[NF9_PSEUDOWIREID].len) {
memcpy(&e->mpls_pw_id.n, pptrs->f_data+tpl->tpl[NF9_PSEUDOWIREID].off, 4);
}
}
}
else if (config.acct_type == ACCT_SF) {
e->mpls_pw_id.n = sample->mpls_vll_vc_id;
}
else return TRUE;

return FALSE;
}

int PT_map_index_fdata_mpls_label_bottom_handler(struct id_entry *e, void *src)
{
struct packet_ptrs *pptrs = (struct packet_ptrs *) src;
Expand Down
5 changes: 5 additions & 0 deletions src/pretag_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ EXT int PT_map_local_pref_handler(char *, struct id_entry *, char *, struct plug
EXT int PT_map_src_comms_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_comms_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_mpls_vpn_rd_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_mpls_pw_id_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_src_mac_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_vlan_id_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
EXT int PT_map_set_tos_handler(char *, struct id_entry *, char *, struct plugin_requests *, int);
Expand All @@ -70,6 +71,7 @@ EXT int PT_map_index_entries_dst_as_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_peer_src_as_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_peer_dst_as_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_mpls_vpn_rd_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_mpls_pw_id_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_mpls_label_bottom_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_src_mac_handler(struct id_entry *, void *);
EXT int PT_map_index_entries_vlan_id_handler(struct id_entry *, void *);
Expand All @@ -82,6 +84,7 @@ EXT int PT_map_index_fdata_dst_as_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_peer_src_as_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_peer_dst_as_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_mpls_vpn_rd_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_mpls_pw_id_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_mpls_label_bottom_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_src_mac_handler(struct id_entry *, void *);
EXT int PT_map_index_fdata_vlan_id_handler(struct id_entry *, void *);
Expand Down Expand Up @@ -130,6 +133,7 @@ EXT int pretag_sample_type_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_sampling_rate_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_direction_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_mpls_vpn_rd_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_mpls_pw_id_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_src_mac_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_vlan_id_handler(struct packet_ptrs *, void *, void *);
EXT int pretag_set_tos_handler(struct packet_ptrs *, void *, void *);
Expand All @@ -146,6 +150,7 @@ EXT int SF_pretag_dst_as_handler(struct packet_ptrs *, void *, void *);
EXT int SF_pretag_src_mac_handler(struct packet_ptrs *, void *, void *);
EXT int SF_pretag_vlan_id_handler(struct packet_ptrs *, void *, void *);
EXT int SF_pretag_sample_type_handler(struct packet_ptrs *, void *, void *);
EXT int SF_pretag_mpls_pw_id_handler(struct packet_ptrs *, void *, void *);

EXT int PM_pretag_src_as_handler(struct packet_ptrs *, void *, void *);
EXT int PM_pretag_dst_as_handler(struct packet_ptrs *, void *, void *);
Expand Down
4 changes: 2 additions & 2 deletions src/sfacctd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1720,10 +1720,10 @@ void readExtendedMplsVC(SFSample *sample)
{
#define SA_MAX_VCNAME_LEN 100
char vc_name[SA_MAX_VCNAME_LEN+1];
u_int32_t vll_vc_id, vc_cos;
u_int32_t vc_cos;

getString(sample, vc_name, SA_MAX_VCNAME_LEN);
vll_vc_id = getData32(sample);
sample->mpls_vll_vc_id = getData32(sample);
vc_cos = getData32(sample);

sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_VC;
Expand Down
1 change: 1 addition & 0 deletions src/sfacctd.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ typedef struct _SFSample {

/* mpls */
SFLAddress mpls_nextHop;
u_int32_t mpls_vll_vc_id;

/* nat */
SFLAddress nat_src;
Expand Down

0 comments on commit 49ab777

Please sign in to comment.