func (c *roaManager) validate(pathList []*table.Path, isMonitor bool) []*api.ROAResult { results := make([]*api.ROAResult, 0) if len(c.clientMap) == 0 { return results } for _, path := range pathList { if path.IsWithdraw { continue } if tree, ok := c.roas[path.GetRouteFamily()]; ok { r, roaList := validatePath(c.AS, tree, path.GetNlri().String(), path.GetAsPath()) if isMonitor && path.Validation() != config.RpkiValidationResultType(r) { apiRoaList := func() []*api.ROA { apiRoaList := make([]*api.ROA, 0) for _, r := range roaList { apiRoaList = append(apiRoaList, r.toApiStruct()...) } return apiRoaList }() rr := &api.ROAResult{ Address: path.GetSource().Address.String(), Timestamp: path.GetTimestamp().Unix(), OriginAs: path.GetSourceAs(), Prefix: path.GetNlri().String(), OldResult: api.ROAResult_ValidationResult(path.Validation().ToInt()), NewResult: api.ROAResult_ValidationResult(r.ToInt()), Roas: apiRoaList, } if b := path.GetAsPath(); b != nil { rr.AspathAttr, _ = b.Serialize() } results = append(results, rr) } path.SetValidation(config.RpkiValidationResultType(r)) } } return results }
func (c *roaManager) validate(pathList []*table.Path) { if len(c.clientMap) == 0 { // RPKI isn't enabled return } for _, path := range pathList { if path.IsWithdraw || path.IsEOR() { continue } if tree, ok := c.Roas[path.GetRouteFamily()]; ok { r := validatePath(c.AS, tree, path.GetNlri().String(), path.GetAsPath()) path.SetValidation(config.RpkiValidationResultType(r)) } } }
func showRoute(pathList []*Path, showAge, showBest, showLabel, isMonitor, printHeader bool) { var pathStrs [][]interface{} maxPrefixLen := 20 maxNexthopLen := 20 maxAsPathLen := 20 maxLabelLen := 10 aspath := func(a bgp.PathAttributeInterface) string { delimiter := make(map[uint8]*AsPathFormat) delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SET] = &AsPathFormat{"{", "}", ","} delimiter[bgp.BGP_ASPATH_ATTR_TYPE_SEQ] = &AsPathFormat{"", "", " "} delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ] = &AsPathFormat{"(", ")", " "} delimiter[bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET] = &AsPathFormat{"[", "]", ","} var segments []string = make([]string, 0) aspaths := a.(*bgp.PathAttributeAsPath).Value for _, aspath := range aspaths { var t uint8 var asnsStr []string switch aspath.(type) { case *bgp.AsPathParam: a := aspath.(*bgp.AsPathParam) t = a.Type for _, asn := range a.AS { asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) } case *bgp.As4PathParam: a := aspath.(*bgp.As4PathParam) t = a.Type for _, asn := range a.AS { asnsStr = append(asnsStr, fmt.Sprintf("%d", asn)) } } s := bytes.NewBuffer(make([]byte, 0, 64)) start := delimiter[t].start end := delimiter[t].end separator := delimiter[t].separator s.WriteString(start) s.WriteString(strings.Join(asnsStr, separator)) s.WriteString(end) segments = append(segments, s.String()) } return strings.Join(segments, " ") } for _, p := range pathList { var nexthop string var aspathstr string s := []string{} for _, a := range p.PathAttrs { switch a.GetType() { case bgp.BGP_ATTR_TYPE_NEXT_HOP: nexthop = a.(*bgp.PathAttributeNextHop).Value.String() case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: n := a.(*bgp.PathAttributeMpReachNLRI).Nexthop if n != nil { nexthop = n.String() } else { nexthop = "fictitious" } case bgp.BGP_ATTR_TYPE_AS_PATH: aspathstr = aspath(a) case bgp.BGP_ATTR_TYPE_AS4_PATH: continue default: s = append(s, a.String()) } } pattrstr := fmt.Sprint(s) if maxNexthopLen < len(nexthop) { maxNexthopLen = len(nexthop) } if maxAsPathLen < len(aspathstr) { maxAsPathLen = len(aspathstr) } best := "" switch config.RpkiValidationResultType(p.Validation) { case config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND: best += "N" case config.RPKI_VALIDATION_RESULT_TYPE_VALID: best += "V" case config.RPKI_VALIDATION_RESULT_TYPE_INVALID: best += "I" } if showBest { if p.Best { best += "*>" } else { best += "* " } } nlri := p.Nlri.String() if maxPrefixLen < len(nlri) { maxPrefixLen = len(nlri) } if isMonitor { title := "ROUTE" if p.IsWithdraw { title = "DELROUTE" } pathStrs = append(pathStrs, []interface{}{title, nlri, nexthop, aspathstr, pattrstr}) } else { args := []interface{}{best, nlri} if showLabel { label := "" switch p.Nlri.(type) { case *bgp.LabeledIPAddrPrefix: label = p.Nlri.(*bgp.LabeledIPAddrPrefix).Labels.String() case *bgp.LabeledIPv6AddrPrefix: label = p.Nlri.(*bgp.LabeledIPv6AddrPrefix).Labels.String() case *bgp.LabeledVPNIPAddrPrefix: label = p.Nlri.(*bgp.LabeledVPNIPAddrPrefix).Labels.String() case *bgp.LabeledVPNIPv6AddrPrefix: label = p.Nlri.(*bgp.LabeledVPNIPv6AddrPrefix).Labels.String() } if maxLabelLen < len(label) { maxLabelLen = len(label) } args = append(args, label) } args = append(args, []interface{}{nexthop, aspathstr}...) if showAge { args = append(args, formatTimedelta(p.Age)) } args = append(args, pattrstr) pathStrs = append(pathStrs, args) } } var format string if isMonitor { format = "[%s] %s via %s aspath [%s] attrs %s\n" } else { format = fmt.Sprintf("%%-3s %%-%ds", maxPrefixLen) if showLabel { format += fmt.Sprintf("%%-%ds ", maxLabelLen) } format += fmt.Sprintf("%%-%ds %%-%ds ", maxNexthopLen, maxAsPathLen) if showAge { format += "%-10s " } format += "%-s\n" } if printHeader { args := []interface{}{"", "Network"} if showLabel { args = append(args, "Labels") } args = append(args, []interface{}{"Next Hop", "AS_PATH"}...) if showAge { args = append(args, "Age") } args = append(args, "Attrs") fmt.Printf(format, args...) } for _, pathStr := range pathStrs { fmt.Printf(format, pathStr...) } }
func showRoute(pathList []*Path, showAge, showBest, showLabel, isMonitor, printHeader bool) { var pathStrs [][]interface{} maxPrefixLen := 20 maxNexthopLen := 20 maxAsPathLen := 20 maxLabelLen := 10 for _, p := range pathList { var nexthop string var aspathstr string s := []string{} for _, a := range p.PathAttrs { switch a.GetType() { case bgp.BGP_ATTR_TYPE_NEXT_HOP: nexthop = a.(*bgp.PathAttributeNextHop).Value.String() case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: n := a.(*bgp.PathAttributeMpReachNLRI).Nexthop if n != nil { nexthop = n.String() } else { nexthop = "fictitious" } case bgp.BGP_ATTR_TYPE_AS_PATH: aspathstr = a.String() case bgp.BGP_ATTR_TYPE_AS4_PATH: continue default: s = append(s, a.String()) } } pattrstr := fmt.Sprint(s) if maxNexthopLen < len(nexthop) { maxNexthopLen = len(nexthop) } if maxAsPathLen < len(aspathstr) { maxAsPathLen = len(aspathstr) } best := "" switch config.RpkiValidationResultType(p.Validation) { case config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND: best += "N" case config.RPKI_VALIDATION_RESULT_TYPE_VALID: best += "V" case config.RPKI_VALIDATION_RESULT_TYPE_INVALID: best += "I" } if showBest { if p.Best { best += "*>" } else { best += "* " } } nlri := p.Nlri.String() if maxPrefixLen < len(nlri) { maxPrefixLen = len(nlri) } if isMonitor { title := "ROUTE" if p.IsWithdraw { title = "DELROUTE" } pathStrs = append(pathStrs, []interface{}{title, nlri, nexthop, aspathstr, pattrstr}) } else { args := []interface{}{best, nlri} if showLabel { label := "" switch p.Nlri.(type) { case *bgp.LabeledIPAddrPrefix: label = p.Nlri.(*bgp.LabeledIPAddrPrefix).Labels.String() case *bgp.LabeledIPv6AddrPrefix: label = p.Nlri.(*bgp.LabeledIPv6AddrPrefix).Labels.String() case *bgp.LabeledVPNIPAddrPrefix: label = p.Nlri.(*bgp.LabeledVPNIPAddrPrefix).Labels.String() case *bgp.LabeledVPNIPv6AddrPrefix: label = p.Nlri.(*bgp.LabeledVPNIPv6AddrPrefix).Labels.String() } if maxLabelLen < len(label) { maxLabelLen = len(label) } args = append(args, label) } args = append(args, []interface{}{nexthop, aspathstr}...) if showAge { args = append(args, formatTimedelta(p.Age)) } args = append(args, pattrstr) pathStrs = append(pathStrs, args) } } var format string if isMonitor { format = "[%s] %s via %s aspath [%s] attrs %s\n" } else { format = fmt.Sprintf("%%-3s %%-%ds", maxPrefixLen) if showLabel { format += fmt.Sprintf("%%-%ds ", maxLabelLen) } format += fmt.Sprintf("%%-%ds %%-%ds ", maxNexthopLen, maxAsPathLen) if showAge { format += "%-10s " } format += "%-s\n" } if printHeader { args := []interface{}{"", "Network"} if showLabel { args = append(args, "Labels") } args = append(args, []interface{}{"Next Hop", "AS_PATH"}...) if showAge { args = append(args, "Age") } args = append(args, "Attrs") fmt.Printf(format, args...) } for _, pathStr := range pathStrs { fmt.Printf(format, pathStr...) } }