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