瀏覽代碼

Update vendored packages

Thomas Frössman 8 年之前
父節點
當前提交
2fd4248745

+ 7
- 4
_vendor/github.com/garyburd/redigo/redis/conn.go 查看文件

@@ -162,7 +162,7 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
162 162
 	return c, nil
163 163
 }
164 164
 
165
-var pathDBRegexp = regexp.MustCompile(`/(\d+)\z`)
165
+var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`)
166 166
 
167 167
 // DialURL connects to a Redis server at the given URL using the Redis
168 168
 // URI scheme. URLs should follow the draft IANA specification for the
@@ -199,9 +199,12 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) {
199 199
 
200 200
 	match := pathDBRegexp.FindStringSubmatch(u.Path)
201 201
 	if len(match) == 2 {
202
-		db, err := strconv.Atoi(match[1])
203
-		if err != nil {
204
-			return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
202
+		db := 0
203
+		if len(match[1]) > 0 {
204
+			db, err = strconv.Atoi(match[1])
205
+			if err != nil {
206
+				return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
207
+			}
205 208
 		}
206 209
 		if db != 0 {
207 210
 			options = append(options, DialDatabase(db))

_vendor/github.com/osrg/gobgp/packet/bgp.go → _vendor/github.com/osrg/gobgp/packet/bgp/bgp.go 查看文件

@@ -29,9 +29,10 @@ import (
29 29
 )
30 30
 
31 31
 const (
32
-	AFI_IP    = 1
33
-	AFI_IP6   = 2
34
-	AFI_L2VPN = 25
32
+	AFI_IP     = 1
33
+	AFI_IP6    = 2
34
+	AFI_L2VPN  = 25
35
+	AFI_OPAQUE = 16397
35 36
 )
36 37
 
37 38
 const (
@@ -46,6 +47,7 @@ const (
46 47
 	SAFI_ROUTE_TARGET_CONSTRTAINS = 132
47 48
 	SAFI_FLOW_SPEC_UNICAST        = 133
48 49
 	SAFI_FLOW_SPEC_VPN            = 134
50
+	SAFI_KEY_VALUE                = 241
49 51
 )
50 52
 
51 53
 const (
@@ -86,9 +88,8 @@ const (
86 88
 	EC_TYPE_NON_TRANSITIVE_OPAQUE                 ExtendedCommunityAttrType = 0x43
87 89
 	EC_TYPE_NON_TRANSITIVE_QOS_MARKING            ExtendedCommunityAttrType = 0x44
88 90
 	EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL       ExtendedCommunityAttrType = 0x80
89
-	//draft-ietf-idr-flowspec-redirect-rt-bis-05
90
-	EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2 ExtendedCommunityAttrType = 0x81
91
-	EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3 ExtendedCommunityAttrType = 0x82
91
+	EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2      ExtendedCommunityAttrType = 0x81 // RFC7674
92
+	EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3      ExtendedCommunityAttrType = 0x82 // RFC7674
92 93
 )
93 94
 
94 95
 // RFC7153 5.2. Registraction for the "Sub-Type" Field
@@ -1164,6 +1165,27 @@ func NewMPLSLabelStack(labels ...uint32) *MPLSLabelStack {
1164 1165
 	return &MPLSLabelStack{labels}
1165 1166
 }
1166 1167
 
1168
+func ParseMPLSLabelStack(buf string) (*MPLSLabelStack, error) {
1169
+	elems := strings.Split(buf, "/")
1170
+	labels := make([]uint32, 0, len(elems))
1171
+	if len(elems) == 0 {
1172
+		goto ERR
1173
+	}
1174
+	for _, elem := range elems {
1175
+		i, err := strconv.Atoi(elem)
1176
+		if err != nil {
1177
+			goto ERR
1178
+		}
1179
+		if i < 0 || i > ((1<<20)-1) {
1180
+			goto ERR
1181
+		}
1182
+		labels = append(labels, uint32(i))
1183
+	}
1184
+	return NewMPLSLabelStack(labels...), nil
1185
+ERR:
1186
+	return nil, fmt.Errorf("invalid mpls label stack format")
1187
+}
1188
+
1167 1189
 //
1168 1190
 // RFC3107 Carrying Label Information in BGP-4
1169 1191
 //
@@ -1338,6 +1360,10 @@ func (l *LabeledIPAddrPrefix) Serialize() ([]byte, error) {
1338 1360
 	return buf, nil
1339 1361
 }
1340 1362
 
1363
+func (l *LabeledIPAddrPrefix) String() string {
1364
+	return fmt.Sprintf("%s/%d", l.Prefix.String(), int(l.Length)-l.Labels.Len()*8)
1365
+}
1366
+
1341 1367
 func NewLabeledIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPAddrPrefix {
1342 1368
 	return &LabeledIPAddrPrefix{
1343 1369
 		IPAddrPrefixDefault{length + uint8(label.Len()*8), net.ParseIP(prefix).To4()},
@@ -1350,6 +1376,10 @@ type LabeledIPv6AddrPrefix struct {
1350 1376
 	LabeledIPAddrPrefix
1351 1377
 }
1352 1378
 
1379
+func (l *LabeledIPv6AddrPrefix) AFI() uint16 {
1380
+	return AFI_IP6
1381
+}
1382
+
1353 1383
 func NewLabeledIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPv6AddrPrefix {
1354 1384
 	return &LabeledIPv6AddrPrefix{
1355 1385
 		LabeledIPAddrPrefix{
@@ -2039,39 +2069,72 @@ const (
2039 2069
 	FLOW_SPEC_TYPE_DSCP
2040 2070
 	FLOW_SPEC_TYPE_FRAGMENT
2041 2071
 	FLOW_SPEC_TYPE_LABEL
2072
+	FLOW_SPEC_TYPE_ETHERNET_TYPE // 14
2073
+	FLOW_SPEC_TYPE_SRC_MAC
2074
+	FLOW_SPEC_TYPE_DST_MAC
2075
+	FLOW_SPEC_TYPE_LLC_DSAP
2076
+	FLOW_SPEC_TYPE_LLC_SSAP
2077
+	FLOW_SPEC_TYPE_LLC_CONTROL
2078
+	FLOW_SPEC_TYPE_SNAP
2079
+	FLOW_SPEC_TYPE_VID
2080
+	FLOW_SPEC_TYPE_COS
2081
+	FLOW_SPEC_TYPE_INNER_VID
2082
+	FLOW_SPEC_TYPE_INNER_COS
2042 2083
 )
2043 2084
 
2044 2085
 var FlowSpecNameMap = map[BGPFlowSpecType]string{
2045
-	FLOW_SPEC_TYPE_UNKNOWN:    "unknown",
2046
-	FLOW_SPEC_TYPE_DST_PREFIX: "destination",
2047
-	FLOW_SPEC_TYPE_SRC_PREFIX: "source",
2048
-	FLOW_SPEC_TYPE_IP_PROTO:   "protocol",
2049
-	FLOW_SPEC_TYPE_PORT:       "port",
2050
-	FLOW_SPEC_TYPE_DST_PORT:   "destination-port",
2051
-	FLOW_SPEC_TYPE_SRC_PORT:   "source-port",
2052
-	FLOW_SPEC_TYPE_ICMP_TYPE:  "icmp-type",
2053
-	FLOW_SPEC_TYPE_ICMP_CODE:  "icmp-code",
2054
-	FLOW_SPEC_TYPE_TCP_FLAG:   "tcp-flags",
2055
-	FLOW_SPEC_TYPE_PKT_LEN:    "packet-length",
2056
-	FLOW_SPEC_TYPE_DSCP:       "dscp",
2057
-	FLOW_SPEC_TYPE_FRAGMENT:   "fragment",
2058
-	FLOW_SPEC_TYPE_LABEL:      "label",
2086
+	FLOW_SPEC_TYPE_UNKNOWN:       "unknown",
2087
+	FLOW_SPEC_TYPE_DST_PREFIX:    "destination",
2088
+	FLOW_SPEC_TYPE_SRC_PREFIX:    "source",
2089
+	FLOW_SPEC_TYPE_IP_PROTO:      "protocol",
2090
+	FLOW_SPEC_TYPE_PORT:          "port",
2091
+	FLOW_SPEC_TYPE_DST_PORT:      "destination-port",
2092
+	FLOW_SPEC_TYPE_SRC_PORT:      "source-port",
2093
+	FLOW_SPEC_TYPE_ICMP_TYPE:     "icmp-type",
2094
+	FLOW_SPEC_TYPE_ICMP_CODE:     "icmp-code",
2095
+	FLOW_SPEC_TYPE_TCP_FLAG:      "tcp-flags",
2096
+	FLOW_SPEC_TYPE_PKT_LEN:       "packet-length",
2097
+	FLOW_SPEC_TYPE_DSCP:          "dscp",
2098
+	FLOW_SPEC_TYPE_FRAGMENT:      "fragment",
2099
+	FLOW_SPEC_TYPE_LABEL:         "label",
2100
+	FLOW_SPEC_TYPE_ETHERNET_TYPE: "ether-type",
2101
+	FLOW_SPEC_TYPE_SRC_MAC:       "source-mac",
2102
+	FLOW_SPEC_TYPE_DST_MAC:       "destination-mac",
2103
+	FLOW_SPEC_TYPE_LLC_DSAP:      "llc-dsap",
2104
+	FLOW_SPEC_TYPE_LLC_SSAP:      "llc-ssap",
2105
+	FLOW_SPEC_TYPE_LLC_CONTROL:   "llc-control",
2106
+	FLOW_SPEC_TYPE_SNAP:          "snap",
2107
+	FLOW_SPEC_TYPE_VID:           "vid",
2108
+	FLOW_SPEC_TYPE_COS:           "cos",
2109
+	FLOW_SPEC_TYPE_INNER_VID:     "inner-vid",
2110
+	FLOW_SPEC_TYPE_INNER_COS:     "inner-cos",
2059 2111
 }
2060 2112
 
2061 2113
 var FlowSpecValueMap = map[string]BGPFlowSpecType{
2062
-	FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PREFIX]: FLOW_SPEC_TYPE_DST_PREFIX,
2063
-	FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PREFIX]: FLOW_SPEC_TYPE_SRC_PREFIX,
2064
-	FlowSpecNameMap[FLOW_SPEC_TYPE_IP_PROTO]:   FLOW_SPEC_TYPE_IP_PROTO,
2065
-	FlowSpecNameMap[FLOW_SPEC_TYPE_PORT]:       FLOW_SPEC_TYPE_PORT,
2066
-	FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PORT]:   FLOW_SPEC_TYPE_DST_PORT,
2067
-	FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PORT]:   FLOW_SPEC_TYPE_SRC_PORT,
2068
-	FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_TYPE]:  FLOW_SPEC_TYPE_ICMP_TYPE,
2069
-	FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_CODE]:  FLOW_SPEC_TYPE_ICMP_CODE,
2070
-	FlowSpecNameMap[FLOW_SPEC_TYPE_TCP_FLAG]:   FLOW_SPEC_TYPE_TCP_FLAG,
2071
-	FlowSpecNameMap[FLOW_SPEC_TYPE_PKT_LEN]:    FLOW_SPEC_TYPE_PKT_LEN,
2072
-	FlowSpecNameMap[FLOW_SPEC_TYPE_DSCP]:       FLOW_SPEC_TYPE_DSCP,
2073
-	FlowSpecNameMap[FLOW_SPEC_TYPE_FRAGMENT]:   FLOW_SPEC_TYPE_FRAGMENT,
2074
-	FlowSpecNameMap[FLOW_SPEC_TYPE_LABEL]:      FLOW_SPEC_TYPE_LABEL,
2114
+	FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PREFIX]:    FLOW_SPEC_TYPE_DST_PREFIX,
2115
+	FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PREFIX]:    FLOW_SPEC_TYPE_SRC_PREFIX,
2116
+	FlowSpecNameMap[FLOW_SPEC_TYPE_IP_PROTO]:      FLOW_SPEC_TYPE_IP_PROTO,
2117
+	FlowSpecNameMap[FLOW_SPEC_TYPE_PORT]:          FLOW_SPEC_TYPE_PORT,
2118
+	FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PORT]:      FLOW_SPEC_TYPE_DST_PORT,
2119
+	FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PORT]:      FLOW_SPEC_TYPE_SRC_PORT,
2120
+	FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_TYPE]:     FLOW_SPEC_TYPE_ICMP_TYPE,
2121
+	FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_CODE]:     FLOW_SPEC_TYPE_ICMP_CODE,
2122
+	FlowSpecNameMap[FLOW_SPEC_TYPE_TCP_FLAG]:      FLOW_SPEC_TYPE_TCP_FLAG,
2123
+	FlowSpecNameMap[FLOW_SPEC_TYPE_PKT_LEN]:       FLOW_SPEC_TYPE_PKT_LEN,
2124
+	FlowSpecNameMap[FLOW_SPEC_TYPE_DSCP]:          FLOW_SPEC_TYPE_DSCP,
2125
+	FlowSpecNameMap[FLOW_SPEC_TYPE_FRAGMENT]:      FLOW_SPEC_TYPE_FRAGMENT,
2126
+	FlowSpecNameMap[FLOW_SPEC_TYPE_LABEL]:         FLOW_SPEC_TYPE_LABEL,
2127
+	FlowSpecNameMap[FLOW_SPEC_TYPE_ETHERNET_TYPE]: FLOW_SPEC_TYPE_ETHERNET_TYPE,
2128
+	FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_MAC]:       FLOW_SPEC_TYPE_SRC_MAC,
2129
+	FlowSpecNameMap[FLOW_SPEC_TYPE_DST_MAC]:       FLOW_SPEC_TYPE_DST_MAC,
2130
+	FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_DSAP]:      FLOW_SPEC_TYPE_LLC_DSAP,
2131
+	FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_SSAP]:      FLOW_SPEC_TYPE_LLC_SSAP,
2132
+	FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_CONTROL]:   FLOW_SPEC_TYPE_LLC_CONTROL,
2133
+	FlowSpecNameMap[FLOW_SPEC_TYPE_SNAP]:          FLOW_SPEC_TYPE_SNAP,
2134
+	FlowSpecNameMap[FLOW_SPEC_TYPE_VID]:           FLOW_SPEC_TYPE_VID,
2135
+	FlowSpecNameMap[FLOW_SPEC_TYPE_COS]:           FLOW_SPEC_TYPE_COS,
2136
+	FlowSpecNameMap[FLOW_SPEC_TYPE_INNER_VID]:     FLOW_SPEC_TYPE_INNER_VID,
2137
+	FlowSpecNameMap[FLOW_SPEC_TYPE_INNER_COS]:     FLOW_SPEC_TYPE_INNER_COS,
2075 2138
 }
2076 2139
 
2077 2140
 func flowSpecPrefixParser(rf RouteFamily, args []string) (FlowSpecComponentInterface, error) {
@@ -2174,6 +2237,29 @@ func flowSpecTcpFlagParser(rf RouteFamily, args []string) (FlowSpecComponentInte
2174 2237
 	return NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, items), nil
2175 2238
 }
2176 2239
 
2240
+func flowSpecEtherTypeParser(rf RouteFamily, args []string) (FlowSpecComponentInterface, error) {
2241
+	ss := make([]string, 0, len(EthernetTypeNameMap))
2242
+	for _, v := range EthernetTypeNameMap {
2243
+		ss = append(ss, v)
2244
+	}
2245
+	protos := strings.Join(ss, "|")
2246
+	exp := regexp.MustCompile(fmt.Sprintf("^%s (((%s) )*)(%s)$", FlowSpecNameMap[FLOW_SPEC_TYPE_ETHERNET_TYPE], protos, protos))
2247
+	elems := exp.FindStringSubmatch(strings.Join(args, " "))
2248
+	items := make([]*FlowSpecComponentItem, 0)
2249
+	eq := 0x1
2250
+	if elems[1] != "" {
2251
+		for _, v := range strings.Split(elems[1], " ") {
2252
+			p, ok := EthernetTypeValueMap[v]
2253
+			if !ok {
2254
+				continue
2255
+			}
2256
+			items = append(items, NewFlowSpecComponentItem(eq, int(p)))
2257
+		}
2258
+	}
2259
+	items = append(items, NewFlowSpecComponentItem(eq, int(EthernetTypeValueMap[elems[4]])))
2260
+	return NewFlowSpecComponent(FLOW_SPEC_TYPE_ETHERNET_TYPE, items), nil
2261
+}
2262
+
2177 2263
 func doFlowSpecNumericParser(rf RouteFamily, args []string, validationFunc func(int) error) (FlowSpecComponentInterface, error) {
2178 2264
 	if afi, _ := RouteFamilyToAfiSafi(rf); afi == AFI_IP && FlowSpecValueMap[args[0]] == FLOW_SPEC_TYPE_LABEL {
2179 2265
 		return nil, fmt.Errorf("flow label spec is only allowed for ipv6")
@@ -2265,40 +2351,77 @@ func flowSpecFragmentParser(rf RouteFamily, args []string) (FlowSpecComponentInt
2265 2351
 	if len(args) < 2 {
2266 2352
 		return nil, fmt.Errorf("invalid flowspec fragment specifier")
2267 2353
 	}
2268
-	value := 0
2269
-	switch args[1] {
2270
-	case "not-a-fragment":
2271
-		if afi, _ := RouteFamilyToAfiSafi(rf); afi == AFI_IP6 {
2272
-			return nil, fmt.Errorf("can't specify not-a-fragment for ipv6")
2354
+	items := make([]*FlowSpecComponentItem, 0)
2355
+	for _, a := range args[1:] {
2356
+		value := 0
2357
+		switch a {
2358
+		case "dont-fragment":
2359
+			if afi, _ := RouteFamilyToAfiSafi(rf); afi == AFI_IP6 {
2360
+				return nil, fmt.Errorf("can't specify dont-fragment for ipv6")
2361
+			}
2362
+			value = 0x1
2363
+		case "is-fragment":
2364
+			value = 0x2
2365
+		case "first-fragment":
2366
+			value = 0x4
2367
+		case "last-fragment":
2368
+			value = 0x8
2369
+		case "not-a-fragment":
2370
+			value = 0x0
2371
+		default:
2372
+			return nil, fmt.Errorf("invalid flowspec fragment specifier")
2273 2373
 		}
2274
-		value = 0x1
2275
-	case "is-a-fragment":
2276
-		value = 0x2
2277
-	case "first-fragment":
2278
-		value = 0x4
2279
-	case "last-fragment":
2280
-		value = 0x8
2281
-	default:
2282
-		return nil, fmt.Errorf("invalid flowspec fragment specifier")
2374
+		items = append(items, NewFlowSpecComponentItem(0, value))
2283 2375
 	}
2284
-	items := []*FlowSpecComponentItem{NewFlowSpecComponentItem(0, value)}
2285 2376
 	return NewFlowSpecComponent(FlowSpecValueMap[args[0]], items), nil
2286 2377
 }
2287 2378
 
2379
+func flowSpecMacParser(rf RouteFamily, args []string) (FlowSpecComponentInterface, error) {
2380
+	if len(args) < 2 {
2381
+		return nil, fmt.Errorf("invalid flowspec dst/src mac")
2382
+	}
2383
+	if rf != RF_FS_L2_VPN {
2384
+		return nil, fmt.Errorf("invalid family")
2385
+	}
2386
+	typ := args[0]
2387
+	mac, err := net.ParseMAC(args[1])
2388
+	if err != nil {
2389
+		return nil, fmt.Errorf("invalid mac")
2390
+	}
2391
+	switch typ {
2392
+	case FlowSpecNameMap[FLOW_SPEC_TYPE_DST_MAC]:
2393
+		return NewFlowSpecDestinationMac(mac), nil
2394
+	case FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_MAC]:
2395
+		return NewFlowSpecSourceMac(mac), nil
2396
+	}
2397
+	return nil, fmt.Errorf("invalid type. only %s or %s allowed", FlowSpecNameMap[FLOW_SPEC_TYPE_DST_MAC], FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_MAC])
2398
+}
2399
+
2288 2400
 var flowSpecParserMap = map[BGPFlowSpecType]func(RouteFamily, []string) (FlowSpecComponentInterface, error){
2289
-	FLOW_SPEC_TYPE_DST_PREFIX: flowSpecPrefixParser,
2290
-	FLOW_SPEC_TYPE_SRC_PREFIX: flowSpecPrefixParser,
2291
-	FLOW_SPEC_TYPE_IP_PROTO:   flowSpecIpProtoParser,
2292
-	FLOW_SPEC_TYPE_PORT:       flowSpecPortParser,
2293
-	FLOW_SPEC_TYPE_DST_PORT:   flowSpecPortParser,
2294
-	FLOW_SPEC_TYPE_SRC_PORT:   flowSpecPortParser,
2295
-	FLOW_SPEC_TYPE_ICMP_TYPE:  flowSpecNumericParser,
2296
-	FLOW_SPEC_TYPE_ICMP_CODE:  flowSpecNumericParser,
2297
-	FLOW_SPEC_TYPE_TCP_FLAG:   flowSpecTcpFlagParser,
2298
-	FLOW_SPEC_TYPE_PKT_LEN:    flowSpecNumericParser,
2299
-	FLOW_SPEC_TYPE_DSCP:       flowSpecDscpParser,
2300
-	FLOW_SPEC_TYPE_FRAGMENT:   flowSpecFragmentParser,
2301
-	FLOW_SPEC_TYPE_LABEL:      flowSpecNumericParser,
2401
+	FLOW_SPEC_TYPE_DST_PREFIX:    flowSpecPrefixParser,
2402
+	FLOW_SPEC_TYPE_SRC_PREFIX:    flowSpecPrefixParser,
2403
+	FLOW_SPEC_TYPE_IP_PROTO:      flowSpecIpProtoParser,
2404
+	FLOW_SPEC_TYPE_PORT:          flowSpecPortParser,
2405
+	FLOW_SPEC_TYPE_DST_PORT:      flowSpecPortParser,
2406
+	FLOW_SPEC_TYPE_SRC_PORT:      flowSpecPortParser,
2407
+	FLOW_SPEC_TYPE_ICMP_TYPE:     flowSpecNumericParser,
2408
+	FLOW_SPEC_TYPE_ICMP_CODE:     flowSpecNumericParser,
2409
+	FLOW_SPEC_TYPE_TCP_FLAG:      flowSpecTcpFlagParser,
2410
+	FLOW_SPEC_TYPE_PKT_LEN:       flowSpecNumericParser,
2411
+	FLOW_SPEC_TYPE_DSCP:          flowSpecDscpParser,
2412
+	FLOW_SPEC_TYPE_FRAGMENT:      flowSpecFragmentParser,
2413
+	FLOW_SPEC_TYPE_LABEL:         flowSpecNumericParser,
2414
+	FLOW_SPEC_TYPE_ETHERNET_TYPE: flowSpecEtherTypeParser,
2415
+	FLOW_SPEC_TYPE_DST_MAC:       flowSpecMacParser,
2416
+	FLOW_SPEC_TYPE_SRC_MAC:       flowSpecMacParser,
2417
+	FLOW_SPEC_TYPE_LLC_DSAP:      flowSpecNumericParser,
2418
+	FLOW_SPEC_TYPE_LLC_SSAP:      flowSpecNumericParser,
2419
+	FLOW_SPEC_TYPE_LLC_CONTROL:   flowSpecNumericParser,
2420
+	FLOW_SPEC_TYPE_SNAP:          flowSpecNumericParser,
2421
+	FLOW_SPEC_TYPE_VID:           flowSpecNumericParser,
2422
+	FLOW_SPEC_TYPE_COS:           flowSpecNumericParser,
2423
+	FLOW_SPEC_TYPE_INNER_VID:     flowSpecNumericParser,
2424
+	FLOW_SPEC_TYPE_INNER_COS:     flowSpecNumericParser,
2302 2425
 }
2303 2426
 
2304 2427
 func ParseFlowSpecComponents(rf RouteFamily, input string) ([]FlowSpecComponentInterface, error) {
@@ -2477,47 +2600,122 @@ func NewFlowSpecSourcePrefix6(prefix AddrPrefixInterface, offset uint8) *FlowSpe
2477 2600
 	return &FlowSpecSourcePrefix6{flowSpecPrefix6{prefix, offset, FLOW_SPEC_TYPE_SRC_PREFIX}}
2478 2601
 }
2479 2602
 
2603
+type flowSpecMac struct {
2604
+	Mac   net.HardwareAddr
2605
+	type_ BGPFlowSpecType
2606
+}
2607
+
2608
+func (p *flowSpecMac) DecodeFromBytes(data []byte) error {
2609
+	if len(data) < 2 || len(data) < 2+int(data[1]) {
2610
+		return fmt.Errorf("not all mac bits available")
2611
+	}
2612
+	p.type_ = BGPFlowSpecType(data[0])
2613
+	p.Mac = net.HardwareAddr(data[2 : 2+int(data[1])])
2614
+	return nil
2615
+}
2616
+
2617
+func (p *flowSpecMac) Serialize() ([]byte, error) {
2618
+	if len(p.Mac) == 0 {
2619
+		return nil, fmt.Errorf("mac unset")
2620
+	}
2621
+	buf := []byte{byte(p.Type()), byte(len(p.Mac))}
2622
+	return append(buf, []byte(p.Mac)...), nil
2623
+}
2624
+
2625
+func (p *flowSpecMac) Len() int {
2626
+	return 2 + len(p.Mac)
2627
+}
2628
+
2629
+func (p *flowSpecMac) Type() BGPFlowSpecType {
2630
+	return p.type_
2631
+}
2632
+
2633
+func (p *flowSpecMac) String() string {
2634
+	return fmt.Sprintf("[%s:%s]", p.Type(), p.Mac.String())
2635
+}
2636
+
2637
+func (p *flowSpecMac) MarshalJSON() ([]byte, error) {
2638
+	return json.Marshal(struct {
2639
+		Type  BGPFlowSpecType `json:"type"`
2640
+		Value string          `json:"value"`
2641
+	}{
2642
+		Type:  p.Type(),
2643
+		Value: p.Mac.String(),
2644
+	})
2645
+}
2646
+
2647
+type FlowSpecSourceMac struct {
2648
+	flowSpecMac
2649
+}
2650
+
2651
+func NewFlowSpecSourceMac(mac net.HardwareAddr) *FlowSpecSourceMac {
2652
+	return &FlowSpecSourceMac{flowSpecMac{Mac: mac, type_: FLOW_SPEC_TYPE_SRC_MAC}}
2653
+}
2654
+
2655
+type FlowSpecDestinationMac struct {
2656
+	flowSpecMac
2657
+}
2658
+
2659
+func NewFlowSpecDestinationMac(mac net.HardwareAddr) *FlowSpecDestinationMac {
2660
+	return &FlowSpecDestinationMac{flowSpecMac{Mac: mac, type_: FLOW_SPEC_TYPE_DST_MAC}}
2661
+}
2662
+
2480 2663
 type FlowSpecComponentItem struct {
2481 2664
 	Op    int `json:"op"`
2482 2665
 	Value int `json:"value"`
2483 2666
 }
2484 2667
 
2668
+func (v *FlowSpecComponentItem) Len() int {
2669
+	return 1 << ((uint32(v.Op) >> 4) & 0x3)
2670
+}
2671
+
2485 2672
 func (v *FlowSpecComponentItem) Serialize() ([]byte, error) {
2486 2673
 	if v.Value < 0 {
2487 2674
 		return nil, fmt.Errorf("invalid value size(too small): %d", v.Value)
2488 2675
 	}
2489 2676
 	if v.Op < 0 || v.Op > math.MaxUint8 {
2490 2677
 		return nil, fmt.Errorf("invalid op size: %d", v.Op)
2491
-	}
2492 2678
 
2493
-	for i := 0; i < 3; i++ {
2494
-		if v.Value < (1 << ((1 << uint(i)) * 8)) {
2495
-			buf := make([]byte, 1+(1<<uint(i)))
2496
-			switch i {
2497
-			case 0:
2498
-				buf[1] = byte(v.Value)
2499
-				v.Op &^= 0x30
2500
-			case 1:
2501
-				binary.BigEndian.PutUint16(buf[1:], uint16(v.Value))
2502
-				v.Op |= 0x10
2503
-				v.Op &^= 0x20
2504
-			case 2:
2505
-				binary.BigEndian.PutUint32(buf[1:], uint32(v.Value))
2506
-				v.Op &^= 0x10
2507
-				v.Op |= 0x20
2508
-			case 3:
2509
-				binary.BigEndian.PutUint64(buf[1:], uint64(v.Value))
2510
-				v.Op |= 0x30
2511
-			}
2512
-			buf[0] = byte(v.Op)
2513
-			return buf, nil
2514
-		}
2515 2679
 	}
2516
-	return nil, fmt.Errorf("invalid value size(too big): %d", v.Value)
2680
+	order := uint32(math.Log2(float64(v.Len())))
2681
+	buf := make([]byte, 1+(1<<order))
2682
+	buf[0] = byte(uint32(v.Op) | order<<4)
2683
+	switch order {
2684
+	case 0:
2685
+		buf[1] = byte(v.Value)
2686
+	case 1:
2687
+		binary.BigEndian.PutUint16(buf[1:], uint16(v.Value))
2688
+	case 2:
2689
+		binary.BigEndian.PutUint32(buf[1:], uint32(v.Value))
2690
+	case 3:
2691
+		binary.BigEndian.PutUint64(buf[1:], uint64(v.Value))
2692
+	default:
2693
+		return nil, fmt.Errorf("invalid value size(too big): %d", v.Value)
2694
+	}
2695
+	return buf, nil
2517 2696
 }
2518 2697
 
2519 2698
 func NewFlowSpecComponentItem(op int, value int) *FlowSpecComponentItem {
2520
-	return &FlowSpecComponentItem{op, value}
2699
+	v := &FlowSpecComponentItem{op, value}
2700
+	order := uint32(math.Log2(float64(v.Len())))
2701
+	// we don't know if not initialized properly or initialized to
2702
+	// zero...
2703
+	if order == 0 {
2704
+		order = func() uint32 {
2705
+			for i := 0; i < 3; i++ {
2706
+				if v.Value < (1 << ((1 << uint(i)) * 8)) {
2707
+					return uint32(i)
2708
+				}
2709
+			}
2710
+			// return invalid order
2711
+			return 4
2712
+		}()
2713
+	}
2714
+	if order > 3 {
2715
+		return nil
2716
+	}
2717
+	v.Op = int(uint32(v.Op) | order<<4)
2718
+	return v
2521 2719
 }
2522 2720
 
2523 2721
 type FlowSpecComponent struct {
@@ -2568,8 +2766,11 @@ func (p *FlowSpecComponent) Serialize() ([]byte, error) {
2568 2766
 }
2569 2767
 
2570 2768
 func (p *FlowSpecComponent) Len() int {
2571
-	buf, _ := p.Serialize()
2572
-	return len(buf)
2769
+	l := 1
2770
+	for _, item := range p.Items {
2771
+		l += (item.Len() + 1)
2772
+	}
2773
+	return l
2573 2774
 }
2574 2775
 
2575 2776
 func (p *FlowSpecComponent) Type() BGPFlowSpecType {
@@ -2626,12 +2827,15 @@ func formatFlag(op int, value int) string {
2626 2827
 }
2627 2828
 
2628 2829
 func formatFragment(op int, value int) string {
2629
-	ss := make([]string, 0, 4)
2630
-	if value&0x1 > 0 {
2830
+	ss := make([]string, 0)
2831
+	if value == 0 {
2631 2832
 		ss = append(ss, "not-a-fragment")
2632 2833
 	}
2834
+	if value&0x1 > 0 {
2835
+		ss = append(ss, "dont-fragment")
2836
+	}
2633 2837
 	if value&0x2 > 0 {
2634
-		ss = append(ss, "is-a-fragment")
2838
+		ss = append(ss, "is-fragment")
2635 2839
 	}
2636 2840
 	if value&0x4 > 0 {
2637 2841
 		ss = append(ss, "first-fragment")
@@ -2645,27 +2849,39 @@ func formatFragment(op int, value int) string {
2645 2849
 	return fmt.Sprintf("%s%s", formatNumericOp(op), ss[0])
2646 2850
 }
2647 2851
 
2852
+func formatEtherType(op int, value int) string {
2853
+	return fmt.Sprintf(" %s", EthernetType(value).String())
2854
+}
2855
+
2648 2856
 var flowSpecFormatMap = map[BGPFlowSpecType]func(op int, value int) string{
2649
-	FLOW_SPEC_TYPE_UNKNOWN:   formatRaw,
2650
-	FLOW_SPEC_TYPE_IP_PROTO:  formatProto,
2651
-	FLOW_SPEC_TYPE_PORT:      formatNumeric,
2652
-	FLOW_SPEC_TYPE_DST_PORT:  formatNumeric,
2653
-	FLOW_SPEC_TYPE_SRC_PORT:  formatNumeric,
2654
-	FLOW_SPEC_TYPE_ICMP_TYPE: formatNumeric,
2655
-	FLOW_SPEC_TYPE_ICMP_CODE: formatNumeric,
2656
-	FLOW_SPEC_TYPE_TCP_FLAG:  formatFlag,
2657
-	FLOW_SPEC_TYPE_PKT_LEN:   formatNumeric,
2658
-	FLOW_SPEC_TYPE_DSCP:      formatNumeric,
2659
-	FLOW_SPEC_TYPE_FRAGMENT:  formatFragment,
2660
-	FLOW_SPEC_TYPE_LABEL:     formatNumeric,
2857
+	FLOW_SPEC_TYPE_UNKNOWN:       formatRaw,
2858
+	FLOW_SPEC_TYPE_IP_PROTO:      formatProto,
2859
+	FLOW_SPEC_TYPE_PORT:          formatNumeric,
2860
+	FLOW_SPEC_TYPE_DST_PORT:      formatNumeric,
2861
+	FLOW_SPEC_TYPE_SRC_PORT:      formatNumeric,
2862
+	FLOW_SPEC_TYPE_ICMP_TYPE:     formatNumeric,
2863
+	FLOW_SPEC_TYPE_ICMP_CODE:     formatNumeric,
2864
+	FLOW_SPEC_TYPE_TCP_FLAG:      formatFlag,
2865
+	FLOW_SPEC_TYPE_PKT_LEN:       formatNumeric,
2866
+	FLOW_SPEC_TYPE_DSCP:          formatNumeric,
2867
+	FLOW_SPEC_TYPE_FRAGMENT:      formatFragment,
2868
+	FLOW_SPEC_TYPE_LABEL:         formatNumeric,
2869
+	FLOW_SPEC_TYPE_ETHERNET_TYPE: formatEtherType,
2870
+	FLOW_SPEC_TYPE_LLC_DSAP:      formatNumeric,
2871
+	FLOW_SPEC_TYPE_LLC_SSAP:      formatNumeric,
2872
+	FLOW_SPEC_TYPE_LLC_CONTROL:   formatNumeric,
2873
+	FLOW_SPEC_TYPE_SNAP:          formatNumeric,
2874
+	FLOW_SPEC_TYPE_VID:           formatNumeric,
2875
+	FLOW_SPEC_TYPE_COS:           formatNumeric,
2876
+	FLOW_SPEC_TYPE_INNER_VID:     formatNumeric,
2877
+	FLOW_SPEC_TYPE_INNER_COS:     formatNumeric,
2661 2878
 }
2662 2879
 
2663 2880
 func (p *FlowSpecComponent) String() string {
2664
-	var f func(op int, value int) string
2665
-	if _, ok := flowSpecFormatMap[p.Type()]; !ok {
2666
-		f = flowSpecFormatMap[FLOW_SPEC_TYPE_UNKNOWN]
2881
+	f := flowSpecFormatMap[FLOW_SPEC_TYPE_UNKNOWN]
2882
+	if _, ok := flowSpecFormatMap[p.Type()]; ok {
2883
+		f = flowSpecFormatMap[p.Type()]
2667 2884
 	}
2668
-	f = flowSpecFormatMap[p.Type()]
2669 2885
 	buf := bytes.NewBuffer(make([]byte, 0, 32))
2670 2886
 	for _, i := range p.Items {
2671 2887
 		buf.WriteString(f(i.Op, i.Value))
@@ -2725,17 +2941,22 @@ type FlowSpecNLRI struct {
2725 2941
 
2726 2942
 func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte) error {
2727 2943
 	var length int
2728
-	if (data[0] >> 4) == 0xf {
2944
+	if (data[0]>>4) == 0xf && len(data) > 2 {
2729 2945
 		length = int(binary.BigEndian.Uint16(data[0:2]))
2730 2946
 		data = data[2:]
2731
-	} else {
2947
+	} else if len(data) > 1 {
2732 2948
 		length = int(data[0])
2733 2949
 		data = data[1:]
2950
+	} else {
2951
+		return fmt.Errorf("not all flowspec component bytes available")
2734 2952
 	}
2735 2953
 
2736 2954
 	n.rf = rf
2737 2955
 
2738 2956
 	for l := length; l > 0; {
2957
+		if len(data) == 0 {
2958
+			return fmt.Errorf("not all flowspec component bytes available")
2959
+		}
2739 2960
 		t := BGPFlowSpecType(data[0])
2740 2961
 		var i FlowSpecComponentInterface
2741 2962
 		switch t {
@@ -2765,9 +2986,25 @@ func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte) error {
2765 2986
 			default:
2766 2987
 				return fmt.Errorf("Invalid RF: %v", rf)
2767 2988
 			}
2989
+		case FLOW_SPEC_TYPE_SRC_MAC:
2990
+			switch rf {
2991
+			case RF_FS_L2_VPN:
2992
+				i = NewFlowSpecSourceMac(nil)
2993
+			default:
2994
+				return fmt.Errorf("invalid family: %v", rf)
2995
+			}
2996
+		case FLOW_SPEC_TYPE_DST_MAC:
2997
+			switch rf {
2998
+			case RF_FS_L2_VPN:
2999
+				i = NewFlowSpecDestinationMac(nil)
3000
+			default:
3001
+				return fmt.Errorf("invalid family: %v", rf)
3002
+			}
2768 3003
 		case FLOW_SPEC_TYPE_IP_PROTO, FLOW_SPEC_TYPE_PORT, FLOW_SPEC_TYPE_DST_PORT, FLOW_SPEC_TYPE_SRC_PORT,
2769 3004
 			FLOW_SPEC_TYPE_ICMP_TYPE, FLOW_SPEC_TYPE_ICMP_CODE, FLOW_SPEC_TYPE_TCP_FLAG, FLOW_SPEC_TYPE_PKT_LEN,
2770
-			FLOW_SPEC_TYPE_DSCP, FLOW_SPEC_TYPE_FRAGMENT, FLOW_SPEC_TYPE_LABEL:
3005
+			FLOW_SPEC_TYPE_DSCP, FLOW_SPEC_TYPE_FRAGMENT, FLOW_SPEC_TYPE_LABEL, FLOW_SPEC_TYPE_ETHERNET_TYPE,
3006
+			FLOW_SPEC_TYPE_LLC_DSAP, FLOW_SPEC_TYPE_LLC_SSAP, FLOW_SPEC_TYPE_LLC_CONTROL, FLOW_SPEC_TYPE_SNAP,
3007
+			FLOW_SPEC_TYPE_VID, FLOW_SPEC_TYPE_COS, FLOW_SPEC_TYPE_INNER_VID, FLOW_SPEC_TYPE_INNER_COS:
2771 3008
 			i = NewFlowSpecComponent(t, nil)
2772 3009
 		default:
2773 3010
 			i = &FlowSpecUnknown{}
@@ -2924,6 +3161,80 @@ func NewFlowSpecIPv6VPN(value []FlowSpecComponentInterface) *FlowSpecIPv6VPN {
2924 3161
 	}}
2925 3162
 }
2926 3163
 
3164
+type FlowSpecL2VPN struct {
3165
+	FlowSpecNLRI
3166
+}
3167
+
3168
+func (n *FlowSpecL2VPN) DecodeFromBytes(data []byte) error {
3169
+	return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data)
3170
+}
3171
+
3172
+func (n *FlowSpecL2VPN) AFI() uint16 {
3173
+	return AFI_L2VPN
3174
+}
3175
+
3176
+func (n *FlowSpecL2VPN) SAFI() uint8 {
3177
+	return SAFI_FLOW_SPEC_VPN
3178
+}
3179
+
3180
+func NewFlowSpecL2VPN(value []FlowSpecComponentInterface) *FlowSpecL2VPN {
3181
+	return &FlowSpecL2VPN{FlowSpecNLRI{
3182
+		Value: value,
3183
+		rf:    RF_FS_L2_VPN,
3184
+	}}
3185
+}
3186
+
3187
+type OpaqueNLRI struct {
3188
+	Length uint8
3189
+	Key    []byte
3190
+}
3191
+
3192
+func (n *OpaqueNLRI) DecodeFromBytes(data []byte) error {
3193
+	n.Length = data[0]
3194
+	if len(data)-1 < int(n.Length) {
3195
+		return fmt.Errorf("Not all OpaqueNLRI bytes available")
3196
+	}
3197
+	n.Key = data[1 : 1+n.Length]
3198
+	return nil
3199
+}
3200
+
3201
+func (n *OpaqueNLRI) Serialize() ([]byte, error) {
3202
+	if len(n.Key) > math.MaxUint8 {
3203
+		return nil, fmt.Errorf("Key length too big")
3204
+	}
3205
+	return append([]byte{byte(len(n.Key))}, n.Key...), nil
3206
+}
3207
+
3208
+func (n *OpaqueNLRI) AFI() uint16 {
3209
+	return AFI_OPAQUE
3210
+}
3211
+
3212
+func (n *OpaqueNLRI) SAFI() uint8 {
3213
+	return SAFI_KEY_VALUE
3214
+}
3215
+
3216
+func (n *OpaqueNLRI) Len() int {
3217
+	return 1 + len(n.Key)
3218
+}
3219
+
3220
+func (n *OpaqueNLRI) String() string {
3221
+	return string(n.Key)
3222
+}
3223
+
3224
+func (n *OpaqueNLRI) MarshalJSON() ([]byte, error) {
3225
+	return json.Marshal(struct {
3226
+		Key string `json:"key"`
3227
+	}{
3228
+		Key: n.String(),
3229
+	})
3230
+}
3231
+
3232
+func NewOpaqueNLRI(key []byte) *OpaqueNLRI {
3233
+	return &OpaqueNLRI{
3234
+		Key: key,
3235
+	}
3236
+}
3237
+
2927 3238
 func AfiSafiToRouteFamily(afi uint16, safi uint8) RouteFamily {
2928 3239
 	return RouteFamily(int(afi)<<16 | int(safi))
2929 3240
 }
@@ -2934,6 +3245,13 @@ func RouteFamilyToAfiSafi(rf RouteFamily) (uint16, uint8) {
2934 3245
 
2935 3246
 type RouteFamily int
2936 3247
 
3248
+func (f RouteFamily) String() string {
3249
+	if n, y := AddressFamilyNameMap[f]; y {
3250
+		return n
3251
+	}
3252
+	return fmt.Sprintf("UnknownFamily(%d)", f)
3253
+}
3254
+
2937 3255
 const (
2938 3256
 	RF_IPv4_UC     RouteFamily = AFI_IP<<16 | SAFI_UNICAST
2939 3257
 	RF_IPv6_UC     RouteFamily = AFI_IP6<<16 | SAFI_UNICAST
@@ -2953,6 +3271,8 @@ const (
2953 3271
 	RF_FS_IPv4_VPN RouteFamily = AFI_IP<<16 | SAFI_FLOW_SPEC_VPN
2954 3272
 	RF_FS_IPv6_UC  RouteFamily = AFI_IP6<<16 | SAFI_FLOW_SPEC_UNICAST
2955 3273
 	RF_FS_IPv6_VPN RouteFamily = AFI_IP6<<16 | SAFI_FLOW_SPEC_VPN
3274
+	RF_FS_L2_VPN   RouteFamily = AFI_L2VPN<<16 | SAFI_FLOW_SPEC_VPN
3275
+	RF_OPAQUE      RouteFamily = AFI_OPAQUE<<16 | SAFI_KEY_VALUE
2956 3276
 )
2957 3277
 
2958 3278
 var AddressFamilyNameMap = map[RouteFamily]string{
@@ -2974,6 +3294,8 @@ var AddressFamilyNameMap = map[RouteFamily]string{
2974 3294
 	RF_FS_IPv4_VPN: "l3vpn-ipv4-flowspec",
2975 3295
 	RF_FS_IPv6_UC:  "ipv6-flowspec",
2976 3296
 	RF_FS_IPv6_VPN: "l3vpn-ipv6-flowspec",
3297
+	RF_FS_L2_VPN:   "l2vpn-flowspec",
3298
+	RF_OPAQUE:      "opaque",
2977 3299
 }
2978 3300
 
2979 3301
 var AddressFamilyValueMap = map[string]RouteFamily{
@@ -2995,6 +3317,8 @@ var AddressFamilyValueMap = map[string]RouteFamily{
2995 3317
 	AddressFamilyNameMap[RF_FS_IPv4_VPN]: RF_FS_IPv4_VPN,
2996 3318
 	AddressFamilyNameMap[RF_FS_IPv6_UC]:  RF_FS_IPv6_UC,
2997 3319
 	AddressFamilyNameMap[RF_FS_IPv6_VPN]: RF_FS_IPv6_VPN,
3320
+	AddressFamilyNameMap[RF_FS_L2_VPN]:   RF_FS_L2_VPN,
3321
+	AddressFamilyNameMap[RF_OPAQUE]:      RF_OPAQUE,
2998 3322
 }
2999 3323
 
3000 3324
 func GetRouteFamily(name string) (RouteFamily, error) {
@@ -3032,6 +3356,10 @@ func NewPrefixFromRouteFamily(afi uint16, safi uint8) (prefix AddrPrefixInterfac
3032 3356
 		prefix = &FlowSpecIPv6Unicast{}
3033 3357
 	case RF_FS_IPv6_VPN:
3034 3358
 		prefix = &FlowSpecIPv6VPN{}
3359
+	case RF_FS_L2_VPN:
3360
+		prefix = &FlowSpecL2VPN{}
3361
+	case RF_OPAQUE:
3362
+		prefix = &OpaqueNLRI{}
3035 3363
 	default:
3036 3364
 		return nil, fmt.Errorf("unknown route family. AFI: %d, SAFI: %d", afi, safi)
3037 3365
 	}
@@ -3093,7 +3421,8 @@ const (
3093 3421
 	BGP_ATTR_TYPE_TUNNEL_ENCAP
3094 3422
 	_
3095 3423
 	_
3096
-	BGP_ATTR_TYPE_AIGP // = 26
3424
+	BGP_ATTR_TYPE_AIGP                     // = 26
3425
+	BGP_ATTR_TYPE_OPAQUE_VALUE BGPAttrType = 41
3097 3426
 )
3098 3427
 
3099 3428
 // NOTIFICATION Error Code  RFC 4271 4.5.
@@ -3186,6 +3515,7 @@ var pathAttrFlags map[BGPAttrType]BGPAttrFlag = map[BGPAttrType]BGPAttrFlag{
3186 3515
 	BGP_ATTR_TYPE_PMSI_TUNNEL:          BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
3187 3516
 	BGP_ATTR_TYPE_TUNNEL_ENCAP:         BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
3188 3517
 	BGP_ATTR_TYPE_AIGP:                 BGP_ATTR_FLAG_OPTIONAL,
3518
+	BGP_ATTR_TYPE_OPAQUE_VALUE:         BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL,
3189 3519
 }
3190 3520
 
3191 3521
 type PathAttributeInterface interface {
@@ -5246,7 +5576,7 @@ func parseFlowSpecExtended(data []byte) (ExtendedCommunityInterface, error) {
5246 5576
 		sample := (data[7]>>1)&0x1 == 1
5247 5577
 		return NewTrafficActionExtended(terminal, sample), nil
5248 5578
 	case EC_SUBTYPE_FLOWSPEC_REDIRECT:
5249
-		//draft-ietf-idr-flowspec-redirect-rt-bis-05
5579
+		// RFC7674
5250 5580
 		switch typ {
5251 5581
 		case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL:
5252 5582
 			as := binary.BigEndian.Uint16(data[2:4])
@@ -6030,6 +6360,35 @@ func NewPathAttributeAigp(values []AigpTLV) *PathAttributeAigp {
6030 6360
 	}
6031 6361
 }
6032 6362
 
6363
+type PathAttributeOpaqueValue struct {
6364
+	PathAttribute
6365
+}
6366
+
6367
+func (p *PathAttributeOpaqueValue) String() string {
6368
+	return fmt.Sprintf("{Value: %s}", string(p.Value))
6369
+}
6370
+
6371
+func (p *PathAttributeOpaqueValue) MarshalJSON() ([]byte, error) {
6372
+	return json.Marshal(struct {
6373
+		Type  BGPAttrType `json:"type"`
6374
+		Value string      `json:"value"`
6375
+	}{
6376
+		Type:  p.GetType(),
6377
+		Value: string(p.Value),
6378
+	})
6379
+}
6380
+
6381
+func NewPathAttributeOpaqueValue(value []byte) *PathAttributeOpaqueValue {
6382
+	t := BGP_ATTR_TYPE_OPAQUE_VALUE
6383
+	return &PathAttributeOpaqueValue{
6384
+		PathAttribute: PathAttribute{
6385
+			Flags: pathAttrFlags[t],
6386
+			Type:  t,
6387
+			Value: value,
6388
+		},
6389
+	}
6390
+}
6391
+
6033 6392
 type PathAttributeUnknown struct {
6034 6393
 	PathAttribute
6035 6394
 }
@@ -6077,6 +6436,8 @@ func GetPathAttribute(data []byte) (PathAttributeInterface, error) {
6077 6436
 		return &PathAttributePmsiTunnel{}, nil
6078 6437
 	case BGP_ATTR_TYPE_AIGP:
6079 6438
 		return &PathAttributeAigp{}, nil
6439
+	case BGP_ATTR_TYPE_OPAQUE_VALUE:
6440
+		return &PathAttributeOpaqueValue{}, nil
6080 6441
 	}
6081 6442
 	return &PathAttributeUnknown{}, nil
6082 6443
 }

_vendor/github.com/osrg/gobgp/packet/bgpattrtype_string.go → _vendor/github.com/osrg/gobgp/packet/bgp/bgpattrtype_string.go 查看文件


_vendor/github.com/osrg/gobgp/packet/bgpcapabilitycode_string.go → _vendor/github.com/osrg/gobgp/packet/bgp/bgpcapabilitycode_string.go 查看文件


_vendor/github.com/osrg/gobgp/packet/bmp.go → _vendor/github.com/osrg/gobgp/packet/bgp/bmp.go 查看文件


_vendor/github.com/osrg/gobgp/packet/constant.go → _vendor/github.com/osrg/gobgp/packet/bgp/constant.go 查看文件

@@ -131,3 +131,64 @@ func (f TCPFlag) String() string {
131 131
 	}
132 132
 	return strings.Join(ss, "|")
133 133
 }
134
+
135
+type EthernetType int
136
+
137
+const (
138
+	IPv4            EthernetType = 0x0800
139
+	ARP             EthernetType = 0x0806
140
+	RARP            EthernetType = 0x8035
141
+	VMTP            EthernetType = 0x805B
142
+	APPLE_TALK      EthernetType = 0x809B
143
+	AARP            EthernetType = 0x80F3
144
+	IPX             EthernetType = 0x8137
145
+	SNMP            EthernetType = 0x814C
146
+	NET_BIOS        EthernetType = 0x8191
147
+	XTP             EthernetType = 0x817D
148
+	IPv6            EthernetType = 0x86DD
149
+	PPPoE_DISCOVERY EthernetType = 0x8863
150
+	PPPoE_SESSION   EthernetType = 0x8864
151
+	LOOPBACK        EthernetType = 0x9000
152
+)
153
+
154
+var EthernetTypeNameMap = map[EthernetType]string{
155
+	IPv4:            "ipv4",
156
+	ARP:             "arp",
157
+	RARP:            "rarp",
158
+	VMTP:            "vmtp",
159
+	APPLE_TALK:      "apple-talk",
160
+	AARP:            "aarp",
161
+	IPX:             "ipx",
162
+	SNMP:            "snmp",
163
+	NET_BIOS:        "net-bios",
164
+	XTP:             "xtp",
165
+	IPv6:            "ipv6",
166
+	PPPoE_DISCOVERY: "pppoe-discovery",
167
+	PPPoE_SESSION:   "pppoe-session",
168
+	LOOPBACK:        "loopback",
169
+}
170
+
171
+var EthernetTypeValueMap = map[string]EthernetType{
172
+	EthernetTypeNameMap[IPv4]:            IPv4,
173
+	EthernetTypeNameMap[ARP]:             ARP,
174
+	EthernetTypeNameMap[RARP]:            RARP,
175
+	EthernetTypeNameMap[VMTP]:            VMTP,
176
+	EthernetTypeNameMap[APPLE_TALK]:      APPLE_TALK,
177
+	EthernetTypeNameMap[AARP]:            AARP,
178
+	EthernetTypeNameMap[IPX]:             IPX,
179
+	EthernetTypeNameMap[SNMP]:            SNMP,
180
+	EthernetTypeNameMap[NET_BIOS]:        NET_BIOS,
181
+	EthernetTypeNameMap[XTP]:             XTP,
182
+	EthernetTypeNameMap[IPv6]:            IPv6,
183
+	EthernetTypeNameMap[PPPoE_DISCOVERY]: PPPoE_DISCOVERY,
184
+	EthernetTypeNameMap[PPPoE_SESSION]:   PPPoE_SESSION,
185
+	EthernetTypeNameMap[LOOPBACK]:        LOOPBACK,
186
+}
187
+
188
+func (t EthernetType) String() string {
189
+	n, ok := EthernetTypeNameMap[t]
190
+	if !ok {
191
+		return fmt.Sprintf("%d", t)
192
+	}
193
+	return n
194
+}

_vendor/github.com/osrg/gobgp/packet/esitype_string.go → _vendor/github.com/osrg/gobgp/packet/bgp/esitype_string.go 查看文件


_vendor/github.com/osrg/gobgp/packet/fsmstate_string.go → _vendor/github.com/osrg/gobgp/packet/bgp/fsmstate_string.go 查看文件


_vendor/github.com/osrg/gobgp/packet/mrt.go → _vendor/github.com/osrg/gobgp/packet/bgp/mrt.go 查看文件


_vendor/github.com/osrg/gobgp/packet/rtr.go → _vendor/github.com/osrg/gobgp/packet/bgp/rtr.go 查看文件


_vendor/github.com/osrg/gobgp/packet/validate.go → _vendor/github.com/osrg/gobgp/packet/bgp/validate.go 查看文件


+ 0
- 63
_vendor/github.com/osrg/gobgp/packet/routefamily_string.go 查看文件

@@ -1,63 +0,0 @@
1
-// generated by stringer -type=RouteFamily bgp.go validate.go constant.go; DO NOT EDIT
2
-
3
-package bgp
4
-
5
-import "fmt"
6
-
7
-const (
8
-	_RouteFamily_name_0 = "RF_IPv4_UCRF_IPv4_MC"
9
-	_RouteFamily_name_1 = "RF_IPv4_MPLS"
10
-	_RouteFamily_name_2 = "RF_ENCAP"
11
-	_RouteFamily_name_3 = "RF_IPv4_VPNRF_IPv4_VPN_MC"
12
-	_RouteFamily_name_4 = "RF_RTC_UCRF_FS_IPv4_UCRF_FS_IPv4_VPN"
13
-	_RouteFamily_name_5 = "RF_IPv6_UCRF_IPv6_MC"
14
-	_RouteFamily_name_6 = "RF_IPv6_MPLS"
15
-	_RouteFamily_name_7 = "RF_IPv6_VPNRF_IPv6_VPN_MC"
16
-	_RouteFamily_name_8 = "RF_VPLS"
17
-	_RouteFamily_name_9 = "RF_EVPN"
18
-)
19
-
20
-var (
21
-	_RouteFamily_index_0 = [...]uint8{0, 10, 20}
22
-	_RouteFamily_index_1 = [...]uint8{0, 12}
23
-	_RouteFamily_index_2 = [...]uint8{0, 8}
24
-	_RouteFamily_index_3 = [...]uint8{0, 11, 25}
25
-	_RouteFamily_index_4 = [...]uint8{0, 9, 22, 36}
26
-	_RouteFamily_index_5 = [...]uint8{0, 10, 20}
27
-	_RouteFamily_index_6 = [...]uint8{0, 12}
28
-	_RouteFamily_index_7 = [...]uint8{0, 11, 25}
29
-	_RouteFamily_index_8 = [...]uint8{0, 7}
30
-	_RouteFamily_index_9 = [...]uint8{0, 7}
31
-)
32
-
33
-func (i RouteFamily) String() string {
34
-	switch {
35
-	case 65537 <= i && i <= 65538:
36
-		i -= 65537
37
-		return _RouteFamily_name_0[_RouteFamily_index_0[i]:_RouteFamily_index_0[i+1]]
38
-	case i == 65540:
39
-		return _RouteFamily_name_1
40
-	case i == 65543:
41
-		return _RouteFamily_name_2
42
-	case 65664 <= i && i <= 65665:
43
-		i -= 65664
44
-		return _RouteFamily_name_3[_RouteFamily_index_3[i]:_RouteFamily_index_3[i+1]]
45
-	case 65668 <= i && i <= 65670:
46
-		i -= 65668
47
-		return _RouteFamily_name_4[_RouteFamily_index_4[i]:_RouteFamily_index_4[i+1]]
48
-	case 131073 <= i && i <= 131074:
49
-		i -= 131073
50
-		return _RouteFamily_name_5[_RouteFamily_index_5[i]:_RouteFamily_index_5[i+1]]
51
-	case i == 131076:
52
-		return _RouteFamily_name_6
53
-	case 131200 <= i && i <= 131201:
54
-		i -= 131200
55
-		return _RouteFamily_name_7[_RouteFamily_index_7[i]:_RouteFamily_index_7[i+1]]
56
-	case i == 1638465:
57
-		return _RouteFamily_name_8
58
-	case i == 1638470:
59
-		return _RouteFamily_name_9
60
-	default:
61
-		return fmt.Sprintf("RouteFamily(%d)", i)
62
-	}
63
-}

+ 21
- 14
_vendor/vendor.json 查看文件

@@ -1,36 +1,43 @@
1 1
 {
2 2
 	"comment": "",
3
-    "ignore": "",
3
+	"ignore": "test",
4 4
 	"package": [
5 5
 		{
6
+			"checksumSHA1": "5rPfda8jFccr3A6heL+JAmi9K9g=",
6 7
 			"path": "github.com/davecgh/go-spew/spew",
7 8
 			"revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d",
8
-			"revisionTime": "2015-11-05T15:09:06-06:00"
9
+			"revisionTime": "2015-11-05T21:09:06Z"
9 10
 		},
10 11
 		{
12
+			"checksumSHA1": "2UmMbNHc8FBr98mJFN1k8ISOIHk=",
11 13
 			"path": "github.com/garyburd/redigo/internal",
12
-			"revision": "836b6e58b3358112c8291565d01c35b8764070d7",
13
-			"revisionTime": "2015-12-19T15:20:44-08:00"
14
+			"revision": "4ed1111375cbeb698249ffe48dd463e9b0a63a7a",
15
+			"revisionTime": "2016-03-02T23:46:02Z"
14 16
 		},
15 17
 		{
18
+			"checksumSHA1": "ThAHOZ525o29BQpFZ1H5UA8QJ+c=",
16 19
 			"path": "github.com/garyburd/redigo/redis",
17
-			"revision": "836b6e58b3358112c8291565d01c35b8764070d7",
18
-			"revisionTime": "2015-12-19T15:20:44-08:00"
20
+			"revision": "4ed1111375cbeb698249ffe48dd463e9b0a63a7a",
21
+			"revisionTime": "2016-03-02T23:46:02Z"
19 22
 		},
20 23
 		{
21
-			"path": "github.com/osrg/gobgp/packet",
22
-			"revision": "e9bc2a896075edd991fd59334dbbab4b3c5b2f68",
23
-			"revisionTime": "2016-01-10T15:53:49+09:00"
24
+			"checksumSHA1": "8oQAG85Lhjj5sE33WYiNO6T6BP4=",
25
+			"path": "github.com/osrg/gobgp/packet/bgp",
26
+			"revision": "a030c52bf2a5b6feda281355599bf22c6b7afdd3",
27
+			"revisionTime": "2016-03-31T21:06:43Z"
24 28
 		},
25 29
 		{
30
+			"checksumSHA1": "vqc3a+oTUGX8PmD0TS+qQ7gmN8I=",
26 31
 			"path": "golang.org/x/net/html",
27
-			"revision": "cbbbe2bc0f2efdd2afb318d93f1eadb19350e4a3",
28
-			"revisionTime": "2016-02-13T01:55:36Z"
32
+			"revision": "3e8a7b0329d536af18e227bb21b6da4d1dbbe180",
33
+			"revisionTime": "2016-03-29T01:55:07Z"
29 34
 		},
30 35
 		{
36
+			"checksumSHA1": "00eQaGynDYrv3tL+C7l9xH0IDZg=",
31 37
 			"path": "golang.org/x/net/html/atom",
32
-			"revision": "cbbbe2bc0f2efdd2afb318d93f1eadb19350e4a3",
33
-			"revisionTime": "2016-02-13T01:55:36Z"
38
+			"revision": "3e8a7b0329d536af18e227bb21b6da4d1dbbe180",
39
+			"revisionTime": "2016-03-29T01:55:07Z"
34 40
 		}
35
-	]
41
+	],
42
+	"rootPath": "github.com/thomasf/internet"
36 43
 }