cccampix: updates from camp

Change-Id: I77e6d9fb6e91b0b7e2d1f89e80164ee8116b5d50
diff --git a/bgpwtf/cccampix/birdie/birdie.go b/bgpwtf/cccampix/birdie/birdie.go
index c063d87..457b567 100644
--- a/bgpwtf/cccampix/birdie/birdie.go
+++ b/bgpwtf/cccampix/birdie/birdie.go
@@ -20,6 +20,7 @@
 	flagRouterID string
 	flagV6       bool
 	flagLocalIP  string
+	flagUpstream bool
 )
 
 func init() {
@@ -32,6 +33,7 @@
 	flag.StringVar(&flagRouterID, "router_id", "", "Router ID")
 	flag.StringVar(&flagLocalIP, "local_ip", "", "Local IP")
 	flag.BoolVar(&flagV6, "v6", false, "V6")
+	flag.BoolVar(&flagUpstream, "upstream", false, "Is an upstream router")
 
 	flag.Parse()
 
@@ -77,6 +79,17 @@
 timeformat protocol iso long;
 timeformat route iso long;
 
+define ourASN = %d;
+define filteredNumber = 65666;
+define customerNumber = 65667;
+define martian = 1;
+define prefixTooLong64 = 2;
+define prefixTooLong24 = 3;
+define pathBogon = 4;
+define pathTooLong = 5;
+define pathFirstNotPeer = 6;
+define prefixFiltered = 9;
+
 protocol device {}
 
 function net_martians() {
@@ -84,14 +97,22 @@
 }
 
 function generic_in() {
-	if net_martians() then return false;
-	if bgp_path.len > 64 then return false;
-	if net.len > 64 then return false;
-	if net.len < 12 then return false;
+	if net_martians() then {
+		bgp_large_community.add((ourASN, filteredNumber, martian));
+		return false;
+	}
+	if bgp_path.len > 64 then {
+		bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
+		return false;
+	}
+	if net.len > 64 then {
+		bgp_large_community.add((ourASN, filteredNumber, prefixTooLong64));
+		return false;
+	}
 	return true;
 }
 `
-		config = fmt.Sprintf(config, flagRouterID)
+		config = fmt.Sprintf(config, flagRouterID, 208521)
 	} else {
 		config = `
 log syslog all;
@@ -104,6 +125,17 @@
 timeformat protocol iso long;
 timeformat route iso long;
 
+define ourASN = %d;
+define filteredNumber = 65666;
+define customerNumber = 65667;
+define martian = 1;
+define prefixTooLong64 = 2;
+define prefixTooLong24 = 3;
+define pathBogon = 4;
+define pathTooLong = 5;
+define pathFirstNotPeer = 6;
+define prefixFiltered = 9;
+
 protocol device {}
 
 function net_martians() {
@@ -112,14 +144,65 @@
 }
 
 function generic_in() {
-	if net_martians() then return false;
-	if bgp_path.len > 64 then return false;
-	if net.len > 24 then return false;
-	if net.len < 8 then return false;
+	if net_martians() then {
+		bgp_large_community.add((ourASN, filteredNumber, martian));
+		return false;
+	}
+	if bgp_path.len > 64 then {
+		bgp_large_community.add((ourASN, filteredNumber, pathTooLong));
+		return false;
+	}
+	if net.len > 24 then {
+		bgp_large_community.add((ourASN, filteredNumber, prefixTooLong24));
+		return false;
+	}
 	return true;
 }
 `
-		config = fmt.Sprintf(config, flagRouterID)
+		config = fmt.Sprintf(config, flagRouterID, 208521)
+	}
+
+	if flagUpstream {
+		config += `
+protocol kernel {
+    scan time 60;
+    import none;
+    export all;
+}
+
+filter UPSTREAM_C3NOC_IN {
+  if net_martians() then reject;
+  if bgp_path.len > 64 then reject;
+  accept;
+}
+
+filter UPSTREAM_C3NOC_OUT {
+  accept;
+}
+
+`
+		if flagV6 {
+			config += `
+protocol bgp UPSTREAM_C3NOC {
+  import filter UPSTREAM_C3NOC_IN;
+  export filter UPSTREAM_C3NOC_OUT;
+  description "UPSTREAM AS13020";
+
+  local 2a0d:eb02:4242:4242::7 as 208521;
+  neighbor 2a0d:eb02:4242:4242::250 as 13020;
+}
+`
+		} else {
+			config += `
+protocol bgp UPSTREAM_C3NOC {
+  import filter UPSTREAM_C3NOC_IN;
+  export filter UPSTREAM_C3NOC_OUT;
+
+  local 185.236.243.7 as 208521;
+  neighbor 185.236.243.250 as 13020;
+}
+`
+		}
 	}
 
 	sort.Slice(res.AsConfigs, func(i, j int) bool {
@@ -166,15 +249,28 @@
 			part := `
 filter %s_in {
 	if !generic_in() then reject;
-	if net ~ [ %s ] then accept;
-	reject;
+	if bgp_path.first != %d then {
+		bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
+		reject;
+	}
+	if bgp_path.last != %d then {
+		bgp_large_community.add((ourASN, filteredNumber, pathFirstNotPeer));
+		reject;
+	}
+	if ! (net ~ [ %s ]) then {
+		bgp_large_community.add((ourASN, filteredNumber, prefixFiltered));
+		reject;
+	}
+	bgp_large_community.add((ourASN, customerNumber, 2137));
+	accept;
 }
 `
-			part = fmt.Sprintf(part, peerid, allowed)
+			part = fmt.Sprintf(part, peerid, asc.Asn, asc.Asn, allowed)
 			config += part
 
 			part = `
 filter %s_out {
+	if (ourASN, customerNumber, 2137) ~ bgp_large_community then reject;
 	accept;
 }
 `
@@ -184,12 +280,15 @@
 			part = `
 protocol bgp %s {
 	local %s as 208521;
+	description "PEER AS%d R%d";
 	neighbor %s as %d;
 	import filter %s_in;
+	import keep filtered on;
+	export filter %s_out;
 	password "%s";
 }
 `
-			part = fmt.Sprintf(part, peerid, flagLocalIP, addr, asc.Asn, peerid, router.Password)
+			part = fmt.Sprintf(part, peerid, flagLocalIP, asc.Asn, i, addr, asc.Asn, peerid, peerid, router.Password)
 			config += part
 		}
 	}