Line data Source code
1 : /* 2 : * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/routing-policy/routing_policy_action.h" 6 : 7 : #include <boost/foreach.hpp> 8 : 9 : #include <algorithm> 10 : #include <sstream> 11 : 12 : #include "bgp/bgp_attr.h" 13 : #include "bgp/bgp_server.h" 14 : #include "bgp/community.h" 15 : 16 : using std::copy; 17 : using std::ostringstream; 18 : using std::string; 19 : using std::vector; 20 : 21 0 : UpdateAsPath::UpdateAsPath(const vector<uint32_t> &asn_list) 22 0 : : asn_list_(asn_list) { 23 0 : } 24 : 25 0 : void UpdateAsPath::operator()(BgpAttr *attr) const { 26 0 : if (!attr) 27 0 : return; 28 0 : BgpAttrDB *attr_db = attr->attr_db(); 29 0 : BgpServer *server = attr_db->server(); 30 0 : if (!server->enable_4byte_as()) { 31 0 : const AsPath *as_path = attr->as_path(); 32 0 : if (as_path) { 33 0 : const AsPathSpec &as_path_spec = as_path->path(); 34 0 : AsPathSpec *as_path_spec_ptr = as_path_spec.Add(asn_list_); 35 0 : attr->set_as_path(as_path_spec_ptr); 36 0 : delete as_path_spec_ptr; 37 : } else { 38 0 : AsPathSpec as_path_spec; 39 0 : AsPathSpec *as_path_spec_ptr = as_path_spec.Add(asn_list_); 40 0 : attr->set_as_path(as_path_spec_ptr); 41 0 : delete as_path_spec_ptr; 42 0 : } 43 : } else { 44 0 : const AsPath4Byte *as_path = attr->aspath_4byte(); 45 0 : if (as_path) { 46 0 : const AsPath4ByteSpec &as_path_spec = as_path->path(); 47 0 : AsPath4ByteSpec *as_path_spec_ptr = as_path_spec.Add(asn_list_); 48 0 : attr->set_aspath_4byte(as_path_spec_ptr); 49 0 : delete as_path_spec_ptr; 50 : } else { 51 0 : AsPath4ByteSpec as_path_spec; 52 0 : AsPath4ByteSpec *as_path_spec_ptr = as_path_spec.Add(asn_list_); 53 0 : attr->set_aspath_4byte(as_path_spec_ptr); 54 0 : delete as_path_spec_ptr; 55 0 : } 56 : } 57 : } 58 : 59 0 : string UpdateAsPath::ToString() const { 60 0 : ostringstream oss; 61 0 : oss << "as-path expand [ "; 62 0 : BOOST_FOREACH(uint32_t asn, asn_list_) { 63 0 : oss << asn << ","; 64 : } 65 0 : oss.seekp(-1, oss.cur); 66 0 : oss << " ]"; 67 0 : return oss.str(); 68 0 : } 69 : 70 0 : bool UpdateAsPath::IsEqual(const RoutingPolicyAction &as_path) const { 71 0 : const UpdateAsPath in_as_path = static_cast<const UpdateAsPath&>(as_path); 72 0 : return (asn_list_ == in_as_path.asn_list_); 73 0 : } 74 : 75 0 : UpdateCommunity::UpdateCommunity(const std::vector<string> communities, 76 0 : string op) { 77 0 : BOOST_FOREACH(const string &community, communities) { 78 0 : uint32_t value = CommunityType::CommunityFromString(community); 79 0 : if (value) communities_.push_back(value); 80 : } 81 0 : std::sort(communities_.begin(), communities_.end()); 82 : std::vector<uint32_t>::iterator it = 83 0 : std::unique(communities_.begin(), communities_.end()); 84 0 : communities_.erase(it, communities_.end()); 85 : 86 0 : if (strcmp(op.c_str(), "add") == 0) { 87 0 : op_ = ADD; 88 0 : } else if (strcmp(op.c_str(), "remove") == 0) { 89 0 : op_ = REMOVE; 90 0 : } else if (strcmp(op.c_str(), "set") == 0) { 91 0 : op_ = SET; 92 : } 93 0 : } 94 : 95 0 : void UpdateCommunity::operator()(BgpAttr *attr) const { 96 0 : if (!attr) return; 97 0 : const Community *comm = attr->community(); 98 0 : BgpAttrDB *attr_db = attr->attr_db(); 99 0 : BgpServer *server = attr_db->server(); 100 0 : CommunityDB *comm_db = server->comm_db(); 101 0 : CommunityPtr new_community = NULL; 102 0 : if (op_ == SET) { 103 0 : new_community = comm_db->SetAndLocate(comm, communities_); 104 0 : } else if (op_ == ADD) { 105 0 : new_community = comm_db->AppendAndLocate(comm, communities_); 106 0 : } else if (op_ == REMOVE) { 107 0 : if (comm) new_community = comm_db->RemoveAndLocate(comm, communities_); 108 : } 109 0 : attr->set_community(new_community); 110 0 : } 111 : 112 0 : string UpdateCommunity::ToString() const { 113 0 : ostringstream oss; 114 0 : if (op_ == SET) oss << "community set [ "; 115 0 : else if (op_ == ADD) oss << "community add [ "; 116 0 : else if (op_ == REMOVE) oss << "community remove [ "; 117 : 118 0 : BOOST_FOREACH(uint32_t community, communities()) { 119 0 : string name = CommunityType::CommunityToString(community); 120 0 : oss << name << ","; 121 0 : } 122 0 : oss.seekp(-1, oss.cur); 123 0 : oss << " ]"; 124 0 : return oss.str(); 125 0 : } 126 : 127 0 : bool UpdateCommunity::IsEqual(const RoutingPolicyAction &community) const { 128 : const UpdateCommunity in_comm = 129 0 : static_cast<const UpdateCommunity&>(community); 130 0 : if (op_ == in_comm.op_) 131 0 : return (communities() == in_comm.communities()); 132 0 : return false; 133 0 : } 134 : 135 0 : UpdateExtCommunity::UpdateExtCommunity(const std::vector<string> &communities, 136 0 : string op) { 137 0 : BOOST_FOREACH(const string &community, communities) { 138 : const ExtCommunity::ExtCommunityList list = 139 0 : ExtCommunity::ExtCommunityFromString(community); 140 0 : if (list.size()) 141 0 : communities_.push_back(list[0]); 142 0 : } 143 0 : std::sort(communities_.begin(), communities_.end()); 144 : ExtCommunity::ExtCommunityList::iterator it = 145 0 : std::unique(communities_.begin(), communities_.end()); 146 0 : communities_.erase(it, communities_.end()); 147 : 148 0 : if (strcmp(op.c_str(), "add") == 0) { 149 0 : op_ = ADD; 150 0 : } else if (strcmp(op.c_str(), "remove") == 0) { 151 0 : op_ = REMOVE; 152 0 : } else if (strcmp(op.c_str(), "set") == 0) { 153 0 : op_ = SET; 154 : } 155 0 : } 156 : 157 0 : void UpdateExtCommunity::operator()(BgpAttr *attr) const { 158 0 : if (!attr) return; 159 0 : const ExtCommunity *comm = attr->ext_community(); 160 0 : BgpAttrDB *attr_db = attr->attr_db(); 161 0 : BgpServer *server = attr_db->server(); 162 0 : ExtCommunityDB *comm_db = server->extcomm_db(); 163 0 : ExtCommunityPtr new_community = NULL; 164 0 : if (op_ == SET) { 165 0 : new_community = comm_db->SetAndLocate(comm, communities_); 166 0 : } else if (op_ == ADD) { 167 0 : new_community = comm_db->AppendAndLocate(comm, communities_); 168 0 : } else if (op_ == REMOVE) { 169 0 : new_community = comm_db->RemoveAndLocate(comm, communities_); 170 : } 171 0 : attr->set_ext_community(new_community); 172 0 : } 173 : 174 0 : string UpdateExtCommunity::ToString() const { 175 0 : ostringstream oss; 176 0 : if (op_ == SET) oss << "Extcommunity set [ "; 177 0 : else if (op_ == ADD) oss << "Extcommunity add [ "; 178 0 : else if (op_ == REMOVE) oss << "Extcommunity remove [ "; 179 : 180 0 : BOOST_FOREACH(ExtCommunity::ExtCommunityValue community, communities()) { 181 0 : string name = ExtCommunity::ToString(community); 182 0 : oss << name << ","; 183 0 : } 184 0 : oss.seekp(-1, oss.cur); 185 0 : oss << " ]"; 186 0 : return oss.str(); 187 0 : } 188 : 189 0 : bool UpdateExtCommunity::IsEqual(const RoutingPolicyAction &community) const { 190 : const UpdateExtCommunity in_comm = 191 0 : static_cast<const UpdateExtCommunity&>(community); 192 0 : if (op_ == in_comm.op_) 193 0 : return (communities() == in_comm.communities()); 194 0 : return false; 195 0 : } 196 : 197 0 : UpdateLocalPref::UpdateLocalPref(uint32_t local_pref) 198 0 : : local_pref_(local_pref) { 199 0 : } 200 : 201 0 : void UpdateLocalPref::operator()(BgpAttr *attr) const { 202 0 : attr->set_local_pref(local_pref_); 203 0 : } 204 : 205 0 : string UpdateLocalPref::ToString() const { 206 0 : ostringstream oss; 207 0 : oss << "local-pref " << local_pref_; 208 0 : return oss.str(); 209 0 : } 210 : 211 0 : bool UpdateLocalPref::IsEqual(const RoutingPolicyAction &local_pref) const { 212 : const UpdateLocalPref in_lp = 213 0 : static_cast<const UpdateLocalPref&>(local_pref); 214 0 : return (local_pref_ == in_lp.local_pref_); 215 0 : } 216 : 217 0 : UpdateMed::UpdateMed(uint32_t med) 218 0 : : med_(med) { 219 0 : } 220 : 221 0 : void UpdateMed::operator()(BgpAttr *attr) const { 222 0 : attr->set_med(med_); 223 0 : } 224 : 225 0 : string UpdateMed::ToString() const { 226 0 : ostringstream oss; 227 0 : oss << "med " << med_; 228 0 : return oss.str(); 229 0 : } 230 : 231 0 : bool UpdateMed::IsEqual(const RoutingPolicyAction &med) const { 232 : const UpdateMed in_med = 233 0 : static_cast<const UpdateMed&>(med); 234 0 : return (med_ == in_med.med_); 235 0 : }