Inethiwekhi ye-IPeE enokunyamezela impazamo isebenzisa izixhobo eziphuculweyo

Mholo. Oku kuthetha ukuba kukho uthungelwano lwabathengi be-5k. Kutshanje umzuzu awumnandi kakhulu weza - embindini womnatha sineBrocade RX8 kwaye yaqala ukuthumela iipakethi ezininzi ezingaziwayo-unicast, ekubeni inethiwekhi yahlulahlulwe ibe yi-vlans - oku akuyongxaki, KODWA kukho. ii-vlan ezikhethekileyo zeedilesi ezimhlophe, njl. kwaye zolulwe macala onke othungelwano. Ke ngoku khawufane ucinge ukuhamba okungenayo kwidilesi yomthengi ongafundiyo njengomfundi womda kwaye oku kuhamba kubhabha ukuya kwikhonkco likanomathotholo ukuya kwilali ethile (okanye yonke) - ijelo livaliwe - abathengi banomsindo - usizi...

Injongo kukuguqula ibug ibe luphawu. Ndandicinga kwicala le-q-in-q kunye nomxhasi ogcweleyo we-vlan, kodwa zonke iintlobo ze-hardware ezifana ne-P3310, xa i-dot1q ivuliwe, iyayeka ukuvumela i-DHCP ukuba idlule, abayazi indlela yokukhetha i-qinq kunye nabaninzi. imigibe yolo hlobo. Yintoni i-ip-unnambered kwaye isebenza njani? Ngokufutshane kakhulu: idilesi yesango + indlela kujongano. Kumsebenzi wethu, kufuneka: sinqumle umzobo, sisasaze iidilesi kubaxumi, songeze iindlela kubathengi ngokusebenzisa ujongano oluthile. Ukwenza njani konke oku? I-Shaper - lisg, i-dhcp - i-db2dhcp kwiiseva ezimbini ezizimeleyo, i-dhcprelay iqhuba kwiiseva zofikelelo, i-ucarp iphinda iqhube kwiiseva zokufikelela - ukwenzela ukugcina. Kodwa njani ukongeza iindlela? Unokongeza yonke into kwangaphambili ngeskripthi esikhulu - kodwa oku akuyonyani. Ngoko ke siya kwenza intonga yokuzibhalela.

Emva kokukhangela ngokucokisekileyo kwi-Intanethi, ndifumene ithala leencwadi elikwinqanaba eliphezulu le-C ++, elikuvumela ukuba urhole i-traffic kakuhle. I-algorithm yenkqubo eyongeza iindlela ngolu hlobo lulandelayo - simamela izicelo ze-arp kwi-interface, ukuba sinedilesi kwi-interface ye-lo kumncedisi eceliwe, ngoko songeza umzila ngolu jongano kwaye songeza i-arp engatshintshiyo. rekhoda kule ip - ngokubanzi, ikopi-uncamathiselo ezimbalwa, isichazi esincinci kwaye ugqibile.

Imithombo ye 'router'

#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

#include <tins/tins.h>
#include <map>
#include <iostream>
#include <functional>
#include <sstream>

using std::cout;
using std::endl;
using std::map;
using std::bind;
using std::string;
using std::stringstream;

using namespace Tins;

class arp_monitor {
public:
    void run(Sniffer &sniffer);
    void reroute();
    void makegws();
    string iface;
    map <string, string> gws;
private:
    bool callback(const PDU &pdu);
    map <string, string> route_map;
    map <string, string> mac_map;
    map <IPv4Address, HWAddress<6>> addresses;
};

void  arp_monitor::makegws() {
    struct ifaddrs *ifAddrStruct = NULL;
    struct ifaddrs *ifa = NULL;
    void *tmpAddrPtr = NULL;
    gws.clear();
    getifaddrs(&ifAddrStruct);
    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
        if (!ifa->ifa_addr) {
            continue;
        }
        string ifName = ifa->ifa_name;
        if (ifName == "lo") {
            char addressBuffer[INET_ADDRSTRLEN];
            if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4
                // is a valid IP4 Address
                tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
                inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
            } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6
                // is a valid IP6 Address
                tmpAddrPtr = &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr;
                inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            } else {
                continue;
            }
            gws[addressBuffer] = addressBuffer;
            cout << "GW " << addressBuffer << " is added" << endl;
        }
    }
    if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);
}

void arp_monitor::run(Sniffer &sniffer) {
    cout << "RUNNED" << endl;
    sniffer.sniff_loop(
            bind(
                    &arp_monitor::callback,
                    this,
                    std::placeholders::_1
            )
    );
}

void arp_monitor::reroute() {
    cout << "REROUTING" << endl;
    map<string, string>::iterator it;
    for ( it = route_map.begin(); it != route_map.end(); it++ ) {
        if (this->gws.count(it->second) && !this->gws.count(it->second)) {
            string cmd = "ip route replace ";
            cmd += it->first;
            cmd += " dev " + this->iface;
            cmd += " src " + it->second;
            cmd += " proto static";
            cout << cmd << std::endl;
            cout << "REROUTE " << it->first << " SRC " << it->second << endl;
            system(cmd.c_str());
            cmd = "arp -s ";
            cmd += it->first;
            cmd += " ";
            cmd += mac_map[it->first];
            cout << cmd << endl;
            system(cmd.c_str());

        }
    }
    for ( it = gws.begin(); it != gws.end(); it++ ) {
	string cmd = "arping -U -s ";
	cmd += it->first;
	cmd += " -I ";
	cmd += this->iface;
	cmd += " -b -c 1 ";
	cmd += it->first;
        system(cmd.c_str());
    }
    cout << "REROUTED" << endl;
}

bool arp_monitor::callback(const PDU &pdu) {
    // Retrieve the ARP layer
    const ARP &arp = pdu.rfind_pdu<ARP>();

    if (arp.opcode() == ARP::REQUEST) {
	
        string target = arp.target_ip_addr().to_string();
        string sender = arp.sender_ip_addr().to_string();
        this->route_map[sender] = target;
        this->mac_map[sender] = arp.sender_hw_addr().to_string();
        cout << "save sender " << sender << ":" << this->mac_map[sender] << " want taregt " << target << endl;
        if (this->gws.count(target) && !this->gws.count(sender)) {
            string cmd = "ip route replace ";
            cmd += sender;
            cmd += " dev " + this->iface;
            cmd += " src " + target;
            cmd += " proto static";
//            cout << cmd << std::endl;
/*            cout << "ARP REQUEST FROM " << arp.sender_ip_addr()
                 << " for address " << arp.target_ip_addr()
                 << " sender hw address " << arp.sender_hw_addr() << std::endl
                 << " run cmd: " << cmd << endl;*/
            system(cmd.c_str());
            cmd = "arp -s ";
            cmd += arp.sender_ip_addr().to_string();
            cmd += " ";
            cmd += arp.sender_hw_addr().to_string();
            cout << cmd << endl;
            system(cmd.c_str());
        }
    }
    return true;
}

arp_monitor monitor;
void reroute(int signum) {
    monitor.makegws();
    monitor.reroute();
}

int main(int argc, char *argv[]) {
    string test;
    cout << sizeof(string) << endl;

    if (argc != 2) {
        cout << "Usage: " << *argv << " <interface>" << endl;
        return 1;
    }
    signal(SIGHUP, reroute);
    monitor.iface = argv[1];
    // Sniffer configuration
    SnifferConfiguration config;
    config.set_promisc_mode(true);
    config.set_filter("arp");

    monitor.makegws();

    try {
        // Sniff on the provided interface in promiscuous mode
        Sniffer sniffer(argv[1], config);

        // Only capture arp packets
        monitor.run(sniffer);
    }
    catch (std::exception &ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
    }
}

iskripthi sokufakela i-libtins

#!/bin/bash

git clone https://github.com/mfontanini/libtins.git
cd libtins
mkdir build
cd build
cmake ../
make
make install
ldconfig

Umyalelo wokwakha i-binary

g++ main.cpp -o arp-rt -O3 -std=c++11 -lpthread -ltins

Indlela yokuyisungula?


start-stop-daemon --start --exec  /opt/ipoe/arp-routes/arp-rt -b -m -p /opt/ipoe/arp-routes/daemons/eth0.800.pid -- eth0.800

Ewe - iya kwakha kwakhona iitafile ngokusekwe kwisiginali yeHUP. Kutheni ungasebenzisi i-netlink? Bubuvila nje kwaye iLinux sisikripthi kwiskripthi - ke yonke into ilungile. Ewe, iindlela ziindlela, yintoni elandelayo? Okulandelayo, kufuneka sithumele iindlela ezikulo mncedisi ukuya kumda - apha, ngenxa ye-hardware efanayo yakudala, sathatha umendo wokumelana kancinci - sabela lo msebenzi kwi-BGP.

uqwalaselo lwe-bgpigama lomamkeli *******
inombolo yokuvula *******
ifayile yelog /var/log/bgp.log
!
# Inombolo ye-AS, iidilesi kunye nothungelwano yinyani
umzila bgp 12345
bgp umzila-id 1.2.3.4
ukusasaza kwakhona kuqhagamshelwe
Ukwaba kwakhona kwi-static
ummelwane 1.2.3.1 kude-njengoko 12345
ummelwane 1.2.3.1 olandelayo-hop-self
ummelwane 1.2.3.1 indlela-maphu akukho nanye
ummelwane 1.2.3.1 ukuthunyelwa ngaphandle kwemephu yendlela
!
Uluhlu lwemvume yokuthumela ngaphandle 1.2.3.0/24
!
Iphepha-mvume lokuthumela ngaphandle kwemephu yendlela 10
Tshatisa idilesi ye-IP yokuthumela ngaphandle
!
Imephu yendlela yokuthumela ngaphandle iyala i-20

Masiqhubeke. Ukuze umncedisi aphendule kwizicelo ze-arp, kufuneka uvule ummeli we-arp.


echo 1 > /proc/sys/net/ipv4/conf/eth0.800/proxy_arp

Masiqhubeke- ucarp. Sibhala imibhalo yokuqaliswa kwalo mmangaliso ngokwethu.

Umzekelo wokuqhuba i-daemon enye


start-stop-daemon --start --exec  /usr/sbin/ucarp -b -m -p /opt/ipoe/ucarp-gen2/daemons/$iface.$vhid.$virtualaddr.pid -- --interface=eth0.800 --srcip=1.2.3.4 --vhid=1 --pass=carpasword --addr=10.10.10.1 --upscript=/opt/ipoe/ucarp-gen2/up.sh --downscript=/opt/ipoe/ucarp-gen2/down.sh -z -k 10 -P --xparam="10.10.10.0/24"

phezulu.sh


#!/bin/bash

iface=$1
addr=$2
gw=$3

vlan=`echo $1 | sed "s/eth0.//"`


ip ad ad $addr/32 dev lo
ip ro add blackhole $gw
echo 1 > /proc/sys/net/ipv4/conf/$iface/proxy_arp

killall -9 dhcrelay
/etc/init.d/dhcrelay zap
/etc/init.d/dhcrelay start


killall -HUP arp-rt

phantsi.sh


#!/bin/bash

iface=$1
addr=$2
gw=$3

ip ad d $addr/32 dev lo
ip ro de blackhole $gw
echo 0 > /proc/sys/net/ipv4/conf/$iface/proxy_arp


killall -9 dhcrelay
/etc/init.d/dhcrelay zap
/etc/init.d/dhcrelay start

Ukuze i-dhcprelay isebenze kujongano, ifuna idilesi. Ngoko ke, kwii-interfaces esizisebenzisayo siya kongeza iidilesi ezisekhohlo - umzekelo 10.255.255.1/32, 10.255.255.2/32, njl. Andiyi kukuxelela indlela yokumisela i-relay - yonke into ilula.

Ngoko yintoni esinayo? Ugcino lwamasango, uqwalaselo oluzenzekelayo lweendlela, i-dhcp. Le yeyona iseti incinci - i-lisg ikwasonga yonke into ngeenxa zonke kwaye sele sinemilo. Kutheni yonke into inde kwaye inzima? Akulula ukuthatha i-accel-ppd kwaye usebenzise i-pppoe ngokupheleleyo? Hayi, ayilulanga - abantu abanakufane bafake i-patchcord kwi-router, singasathethi ke ngepppoe. I-accel-ppp yinto epholileyo-kodwa ayizange isisebenzele-zininzi iimpazamo kwikhowudi-iyadilika, inqumle ngokugwenxa, kwaye eyona nto ibuhlungu kukuba ukuba ikhanya - ke abantu kufuneka balayishe kwakhona. yonke into - iifowuni zibomvu - ayizange isebenze konke konke. Yintoni i-advantage yokusebenzisa i-ucarp kune-keepalived? Ewe, kuyo yonke into - kukho amasango ayi-100, agcinwe kwaye enye impazamo kwi-config - yonke into ayisebenzi. Isango eli-1 alisebenzi nge-ucarp. Ngokuphathelele ukhuseleko, bathi abasekhohlo baya kubhalisa iidilesi zabo kwaye bazisebenzise kwisabelo - ukulawula lo mzuzu, sibeka i-dhcp-snooping + source-guard + inspection of arp kuzo zonke iiswitshi / olts / iziseko. Ukuba umxhasi akanayo i-dhpc kodwa engatshintshiyo-uluhlu lofikelelo-kwizibuko.

Kwakutheni ukuze kwenziwe konke oku? Ukutshabalalisa itrafikhi engafunwayo. Ngoku inguqu nganye ine-vlan yayo kwaye i-unicast engaziwayo ayisayi kuba yoyikeka, kuba ifuna kuphela ukuya kwi-port enye kwaye ingabikho kubo bonke ... Ewe, iziphumo zecala ziyi-config yezixhobo ezisemgangathweni, ukuphumelela okukhulu ekunikezeni indawo yedilesi.

Uyiqwalasela njani i-lisg sisihloko esahlukileyo. Uqhagamshelo lwamathala eencwadi luncanyathiselwe. Mhlawumbi oku kungasentla kuya kunceda umntu ekuphumezeni iinjongo zakhe. Inguqulo yesi-6 ayikaphunyezwa kuthungelwano lwethu okwangoku - kodwa kuya kubakho ingxaki - kukho izicwangciso zokuphinda ubhale kwakhona i-lisg yenguqulo yesi-6, kwaye kuya kuba yimfuneko ukulungisa inkqubo eyongeza iindlela.

Linux ISG
DB2DHCP
Ii-Libtins

umthombo: www.habr.com

Yongeza izimvo