Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/l3vpn/inetvpn_route.h" 6 : 7 : #include <algorithm> 8 : 9 : #include "bgp/l3vpn/inetvpn_table.h" 10 : 11 : using std::copy; 12 : using std::string; 13 : using std::vector; 14 : 15 0 : InetVpnRoute::InetVpnRoute(const InetVpnPrefix &prefix) 16 0 : : prefix_(prefix) { 17 0 : } 18 : 19 0 : int InetVpnRoute::CompareTo(const Route &rhs) const { 20 0 : const InetVpnRoute &other = static_cast<const InetVpnRoute &>(rhs); 21 0 : int res = prefix_.route_distinguisher().CompareTo( 22 : other.prefix_.route_distinguisher()); 23 0 : if (res != 0) { 24 0 : return res; 25 : } 26 0 : Ip4Address laddr = prefix_.addr(); 27 0 : Ip4Address raddr = other.prefix_.addr(); 28 0 : if (laddr < raddr) { 29 0 : return -1; 30 : } 31 0 : if (laddr > raddr) { 32 0 : return 1; 33 : } 34 0 : if (prefix_.prefixlen() < other.prefix_.prefixlen()) { 35 0 : return -1; 36 : } 37 0 : if (prefix_.prefixlen() > other.prefix_.prefixlen()) { 38 0 : return 1; 39 : } 40 0 : return 0; 41 : } 42 : 43 0 : string InetVpnRoute::ToString() const { 44 0 : string repr = prefix_.route_distinguisher().ToString() + ":"; 45 0 : repr += prefix_.addr().to_string(); 46 : char strplen[4]; 47 0 : snprintf(strplen, sizeof(strplen), "/%d", prefix_.prefixlen()); 48 0 : repr.append(strplen); 49 : 50 0 : return repr; 51 0 : } 52 : 53 0 : void InetVpnRoute::SetKey(const DBRequestKey *reqkey) { 54 0 : const InetVpnTable::RequestKey *key = 55 : static_cast<const InetVpnTable::RequestKey *>(reqkey); 56 0 : prefix_ = key->prefix; 57 0 : } 58 : 59 0 : void InetVpnRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, 60 : const BgpAttr *attr, 61 : uint32_t label, 62 : uint32_t l3_label) const { 63 0 : prefix_.BuildProtoPrefix(label, prefix, attr); 64 0 : } 65 : 66 0 : void InetVpnRoute::BuildBgpProtoNextHop(vector<uint8_t> &nh, 67 : IpAddress nexthop) const { 68 0 : nh.resize(4+RouteDistinguisher::kSize); 69 0 : const Ip4Address::bytes_type &addr_bytes = nexthop.to_v4().to_bytes(); 70 0 : copy(addr_bytes.begin(), addr_bytes.end(), 71 0 : nh.begin() + RouteDistinguisher::kSize); 72 0 : } 73 : 74 0 : DBEntryBase::KeyPtr InetVpnRoute::GetDBRequestKey() const { 75 : InetVpnTable::RequestKey *key = 76 0 : new InetVpnTable::RequestKey(GetPrefix(), NULL); 77 0 : return KeyPtr(key); 78 : } 79 : 80 : // Check whether 'this' is more specific than rhs. 81 0 : bool InetVpnRoute::IsMoreSpecific(const string &match) const { 82 0 : boost::system::error_code ec; 83 : 84 0 : InetVpnPrefix prefix = InetVpnPrefix::FromString(match, &ec); 85 0 : if (!ec) { 86 0 : return GetPrefix().IsMoreSpecific(prefix); 87 : } 88 : 89 0 : return false; 90 : } 91 : 92 : // Check whether 'this' is less specific than rhs. 93 0 : bool InetVpnRoute::IsLessSpecific(const string &match) const { 94 0 : boost::system::error_code ec; 95 : 96 0 : InetVpnPrefix prefix = InetVpnPrefix::FromString(match, &ec); 97 0 : if (!ec) { 98 0 : return prefix.IsMoreSpecific(GetPrefix()); 99 : } 100 : 101 0 : return false; 102 : }