diff --git a/go.mod b/go.mod index c9debfef..d376c1d9 100644 --- a/go.mod +++ b/go.mod @@ -21,21 +21,27 @@ require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/florianl/go-tc v0.4.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/spec v0.20.8 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/josharian/native v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mdlayher/netlink v1.6.0 // indirect + github.com/mdlayher/socket v0.1.1 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect golang.org/x/net v0.9.0 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/tools v0.8.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index f091bbab..945b1bef 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,9 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= +github.com/cilium/ebpf v0.8.1/go.mod h1:f5zLIM0FSNuAkSyLAN7X+Hy6yznlF1mNiWUMfxMtrgk= github.com/cilium/ebpf v0.10.0 h1:nk5HPMeoBXtOzbkZBWym+ZWq1GIiHUsBFXxwewXAHLQ= github.com/cilium/ebpf v0.10.0/go.mod h1:DPiVdY/kT534dgc9ERmvP8mWA+9gvwgKfRvk4nNWnoE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -11,6 +14,10 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/florianl/go-tc v0.4.2 h1:jan5zcOWCLhA9SRBHZhQ0SSAq7cmDUagiRPngAi5AOQ= +github.com/florianl/go-tc v0.4.2/go.mod h1:2W1jSMFryiYlpQigr4ZpSSpE9XNze+bW7cTsCXWbMwo= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= @@ -35,12 +42,34 @@ github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgj github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= +github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= +github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= +github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= +github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok= +github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw= +github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs= +github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA= +github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U= +github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo= +github.com/jsimonetti/rtnetlink v0.0.0-20211022192332-93da33804786/go.mod h1:v4hqbTdfQngbVSZJVWUhGE/lbTFf9jb+ygmNUDQMuOs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -57,6 +86,23 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= +github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= +github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= +github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= +github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= +github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o= +github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8= +github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU= +github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU= +github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys= +github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8= +github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqAS9cNgn6Q= +github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0= +github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA= +github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc= +github.com/mdlayher/socket v0.1.1 h1:q3uOGirUPfAV2MUoaC7BavjQ154J7+JOkTWyiV+intI= +github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -73,6 +119,7 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/robfig/config v0.0.0-20141207224736-0f78529c8c7e h1:3/9k/etUfgykjM3Rx8X0echJzo7gNNeND/ubPkqYw1k= github.com/robfig/config v0.0.0-20141207224736-0f78529c8c7e/go.mod h1:Zerq1qYbCKtIIU9QgPydffGlpYfZ8KI/si49wuTLY/Q= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= @@ -97,32 +144,69 @@ github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKik github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -141,6 +225,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/kf/bpf.go b/kf/bpf.go index 02bd6938..1882760c 100644 --- a/kf/bpf.go +++ b/kf/bpf.go @@ -14,6 +14,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/url" "os" @@ -31,8 +32,13 @@ import ( "github.com/l3af-project/l3afd/stats" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/link" + "github.com/cilium/ebpf/rlimit" + tc "github.com/florianl/go-tc" + "github.com/florianl/go-tc/core" ps "github.com/mitchellh/go-ps" "github.com/rs/zerolog/log" + "golang.org/x/sys/unix" ) var ( @@ -55,12 +61,15 @@ type BPF struct { RestartCount int // To track restart count PrevMapNamePath string // Previous Map name with path to link MapNamePath string // Map name with path - ProgID int // eBPF Program ID + ProgID ebpf.ProgramID // eBPF Program ID BpfMaps map[string]BPFMap // Config maps passed as map-args, Map name is Key MetricsBpfMaps map[string]*MetricsBPFMap // Metrics map name+key+aggregator is key Ctx context.Context `json:"-"` Done chan bool `json:"-"` + CollectionRef *ebpf.Collection `json:"_"` // eBPF Collection reference + ProgMapID ebpf.MapID hostConfig *config.Config + TCFilter *tc.Filter } func NewBpfProgram(ctx context.Context, program models.BPFProgram, conf *config.Config) *BPF { @@ -95,8 +104,6 @@ func LoadRootProgram(ifaceName string, direction string, progType string, conf * MapName: conf.XDPRootMapName, Version: conf.XDPRootVersion, UserProgramDaemon: false, - CmdStart: conf.XDPRootCommand, - CmdStop: conf.XDPRootCommand, CmdStatus: "", AdminStatus: models.Enabled, ProgType: models.XDPType, @@ -104,6 +111,8 @@ func LoadRootProgram(ifaceName string, direction string, progType string, conf * StartArgs: map[string]interface{}{}, StopArgs: map[string]interface{}{}, StatusArgs: map[string]interface{}{}, + ObjectFile: filepath.Join(conf.BPFDir, conf.XDPRootPackageName, conf.XDPRootVersion, strings.Split(conf.XDPRootArtifact, ".")[0], conf.XDPRootObjectFile), + EntryFunctionName: conf.XDPRootEntryFunctionName, }, RestartCount: 0, Cmd: nil, @@ -119,8 +128,6 @@ func LoadRootProgram(ifaceName string, direction string, progType string, conf * Artifact: conf.TCRootArtifact, Version: conf.TCRootVersion, UserProgramDaemon: false, - CmdStart: conf.TCRootCommand, - CmdStop: conf.TCRootCommand, CmdStatus: "", AdminStatus: models.Enabled, ProgType: models.TCType, @@ -137,36 +144,45 @@ func LoadRootProgram(ifaceName string, direction string, progType string, conf * if direction == models.IngressType { rootProgBPF.Program.MapName = conf.TCRootIngressMapName rootProgBPF.MapNamePath = filepath.Join(conf.BpfMapDefaultPath, conf.TCRootIngressMapName) + rootProgBPF.Program.ObjectFile = filepath.Join(conf.BPFDir, conf.TCRootPackageName, conf.TCRootVersion, strings.Split(conf.TCRootArtifact, ".")[0], conf.TCRootIngressObjectFile) + rootProgBPF.Program.EntryFunctionName = conf.TCRootIngressEntryFunctionName } else if direction == models.EgressType { rootProgBPF.Program.MapName = conf.TCRootEgressMapName rootProgBPF.MapNamePath = filepath.Join(conf.BpfMapDefaultPath, conf.TCRootEgressMapName) + rootProgBPF.Program.ObjectFile = filepath.Join(conf.BPFDir, conf.TCRootPackageName, conf.TCRootVersion, strings.Split(conf.TCRootArtifact, ".")[0], conf.TCRootEgressObjectFile) + rootProgBPF.Program.EntryFunctionName = conf.TCRootEgressEntryFunctionName } default: return nil, fmt.Errorf("unknown direction %s for root program in iface %s", direction, ifaceName) } - // Loading default arguments - rootProgBPF.Program.StartArgs["cmd"] = models.StartType - rootProgBPF.Program.StopArgs["cmd"] = models.StopType - if err := rootProgBPF.VerifyAndGetArtifacts(conf); err != nil { log.Error().Err(err).Msg("failed to get root artifacts") return nil, err } // On l3afd crashing scenario verify root program are unloaded properly by checking existence of persisted maps - // if map file exists then root program is still running + // if map file exists then root program didn't clean up pinned map files if fileExists(rootProgBPF.MapNamePath) { - log.Warn().Msgf("previous instance of root program %s is running, stopping it ", rootProgBPF.Program.Name) - if err := rootProgBPF.Stop(ifaceName, direction, conf.BpfChainingEnabled); err != nil { - return nil, fmt.Errorf("failed to stop root program on iface %s name %s direction %s", ifaceName, rootProgBPF.Program.Name, direction) - } + log.Warn().Msgf("previous instance of root program %s persisted map %s file exists", rootProgBPF.Program.Name, rootProgBPF.MapNamePath) + rootProgBPF.RemoveMapFile() } - if err := rootProgBPF.Start(ifaceName, direction, conf.BpfChainingEnabled); err != nil { - return nil, fmt.Errorf("failed to start root program on interface %s, err: %v", ifaceName, err) + if progType == models.XDPType { + rlimit.RemoveMemlock() + if err := rootProgBPF.LoadXDPRootProgram(ifaceName, rootProgBPF); err != nil { + return nil, fmt.Errorf("failed to load root program on iface %s name %s direction %s", ifaceName, rootProgBPF.Program.Name, direction) + } + } else if progType == models.TCType { + if err := rootProgBPF.LoadTCRootProgram(ifaceName, direction, rootProgBPF); err != nil { + return nil, fmt.Errorf("failed to load root program on iface %s name %s direction %s", ifaceName, rootProgBPF.Program.Name, direction) + } } + //if err := rootProgBPF.Start(ifaceName, direction, conf.BpfChainingEnabled); err != nil { + // return nil, fmt.Errorf("failed to start root program on interface %s, err: %v", ifaceName, err) + //} + return rootProgBPF, nil } @@ -243,6 +259,19 @@ func (b *BPF) Stop(ifaceName, direction string, chain bool) error { stats.SetWithVersion(0.0, stats.NFRunning, b.Program.Name, b.Program.Version, direction, ifaceName) if len(b.Program.CmdStop) < 1 { + // Program ref handle - loaded from l3afd + if b.CollectionRef != nil { + if err := b.UnLoadProgram(ifaceName, direction); err != nil { + return fmt.Errorf("BPFProgram %s unload failed with error: %v", b.Program.Name, err) + } + log.Info().Msgf("%s => %s direction => %s - program is unloaded/detached successfully", ifaceName, b.Program.Name, direction) + return nil + } else if len(b.Program.ObjectFile) > 0 { + b.RemoveMapFile() + return nil + } + + // Loaded using user program if err := b.ProcessTerminate(); err != nil { return fmt.Errorf("BPFProgram %s process terminate failed with error: %v", b.Program.Name, err) } @@ -426,7 +455,7 @@ func (b *BPF) Start(ifaceName, direction string, chain bool) error { // KFconfigs if len(b.Program.CmdConfig) > 0 && len(b.Program.ConfigFilePath) > 0 { - log.Info().Msgf("KP specific config monitoring - %s", b.Program.ConfigFilePath) + log.Info().Msgf("eBPF program specific config monitoring - %s", b.Program.ConfigFilePath) b.Done = make(chan bool) go b.RunKFConfigs() } @@ -874,7 +903,7 @@ func (b *BPF) PutNextProgFDFromID(progID int) error { } // GetProgID - This returns ID of the bpf program -func (b *BPF) GetProgID() (int, error) { +func (b *BPF) GetProgID() (ebpf.ProgramID, error) { ebpfMap, err := ebpf.LoadPinnedMap(b.PrevMapNamePath, &ebpf.LoadPinOptions{ReadOnly: true}) if err != nil { @@ -882,7 +911,7 @@ func (b *BPF) GetProgID() (int, error) { return 0, fmt.Errorf("unable to access pinned prog map %s %v", b.PrevMapNamePath, err) } defer ebpfMap.Close() - var value int + var value ebpf.ProgramID key := 0 if err = ebpfMap.Lookup(unsafe.Pointer(&key), unsafe.Pointer(&value)); err != nil { @@ -1041,6 +1070,254 @@ func (b *BPF) VerifyMetricsMapsVanish() error { return err } +func (b *BPF) LoadXDPRootProgram(ifaceName string, eBPFProgram *BPF) error { + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + log.Fatal().Msgf("lookup network iface %q: %s", ifaceName, err) + } + + CollectionRef, err := ebpf.LoadCollection(eBPFProgram.Program.ObjectFile) + if err != nil { + return fmt.Errorf("%s: loading of xdp root failed", eBPFProgram.Program.ObjectFile) + } + //defer prg.Close() + b.CollectionRef = CollectionRef + bpfRootProg := CollectionRef.Programs[eBPFProgram.Program.EntryFunctionName] + bpfRootMap := CollectionRef.Maps[eBPFProgram.Program.MapName] + + // Pinning root map + rootArrayMapFileName := filepath.Join(b.hostConfig.BpfMapDefaultPath, eBPFProgram.Program.MapName) + if err := bpfRootMap.Pin(rootArrayMapFileName); err != nil { + return fmt.Errorf("%s:failed to pin the map", rootArrayMapFileName) + } + + // Attach the program + _, err = link.AttachXDP(link.XDPOptions{ + Program: bpfRootProg, + Interface: iface.Index, + }) + + if err != nil { + return fmt.Errorf("could not attach XDP program: %s", err) + } + + progInfo, err := bpfRootProg.Info() + if err != nil { + return fmt.Errorf("could not get program info of xdp root program: %s", err) + } + + ok := false + b.ProgID, ok = progInfo.ID() + if !ok { + return fmt.Errorf("failed to fetch the xdp root Program ID") + } + + ebpfInfo, err := bpfRootMap.Info() + if err != nil { + return fmt.Errorf("fetching map info failed %v", err) + } + + b.ProgMapID, ok = ebpfInfo.ID() + if !ok { + return fmt.Errorf("fetching map id failed %v", err) + } + + return nil +} + +func (b *BPF) LoadTCRootProgram(ifaceName, direction string, eBPFProgram *BPF) error { + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + log.Fatal().Msgf("lookup network iface %q: %s", ifaceName, err) + } + + // verify and add attribute clsact + tcgo, err := tc.Open(&tc.Config{}) + if err != nil { + return fmt.Errorf("could not open rtnetlink socket: %v", err) + } + + clsactFound := false + // get all the qdiscs from all interfaces + qdiscs, err := tcgo.Qdisc().Get() + if err != nil { + return fmt.Errorf("could not get qdiscs: %v", err) + } + for _, qdisc := range qdiscs { + iface, err := net.InterfaceByIndex(int(qdisc.Ifindex)) + if err != nil { + return fmt.Errorf("could not get interface from id %d: %v", qdisc.Ifindex, err) + } + if iface.Name == ifaceName && qdisc.Kind == "clsact" { + clsactFound = true + } + } + + if !clsactFound { + qdisc := tc.Object{ + Msg: tc.Msg{ + Family: unix.AF_UNSPEC, + Ifindex: uint32(iface.Index), + Handle: core.BuildHandle(tc.HandleRoot, 0x0000), + Parent: tc.HandleIngress, + Info: 0, + }, + Attribute: tc.Attribute{ + Kind: "clsact", + }, + } + + if err := tcgo.Qdisc().Add(&qdisc); err != nil { + log.Info().Msgf("could not assign clsact to %s: %v, its already exists", ifaceName, err) + } + } + + CollectionRef, err := ebpf.LoadCollection(eBPFProgram.Program.ObjectFile) + if err != nil { + log.Error().Msgf("loading of tc root %s failed direction %s", eBPFProgram.Program.ObjectFile, direction) + return fmt.Errorf("%s: loading of tc root failed", eBPFProgram.Program.ObjectFile) + } + + // storing collection reference pointer + b.CollectionRef = CollectionRef + + var bpfRootProg *ebpf.Program + var bpfRootMap *ebpf.Map + var rootArrayMapFileName string + + bpfRootProg = CollectionRef.Programs[eBPFProgram.Program.EntryFunctionName] + bpfRootMap = CollectionRef.Maps[strings.Split(eBPFProgram.Program.MapName, "/")[2]] + rootArrayMapFileName = filepath.Join(b.hostConfig.BpfMapDefaultPath, eBPFProgram.Program.MapName) + + // Pinning root program + if err := bpfRootMap.Pin(rootArrayMapFileName); err != nil { + return fmt.Errorf("%s failed to pin the map", rootArrayMapFileName) + } + + var parent uint32 + if direction == models.IngressType { + parent = tc.HandleMinIngress + } else if direction == models.EgressType { + parent = tc.HandleMinEgress + } + + progFD := uint32(bpfRootProg.FD()) + bpfFlag := uint32(0x1) + filter := tc.Object{ + Msg: tc.Msg{ + Family: unix.AF_UNSPEC, + Ifindex: uint32(iface.Index), + Handle: 0, + Parent: core.BuildHandle(tc.HandleRoot, parent), + Info: 0x300, + }, + Attribute: tc.Attribute{ + Kind: "bpf", + BPF: &tc.Bpf{ + FD: &progFD, + Flags: &bpfFlag, + }, + }, + } + + // Storing Filter handle + b.TCFilter = tcgo.Filter() + + // Attaching / Adding as filter + if err := b.TCFilter.Add(&filter); err != nil { + return fmt.Errorf("could not attach filter for eBPF program: %v", err) + } + + return nil +} + +func (b *BPF) UnLoadProgram(ifaceName, direction string) error { + _, err := net.InterfaceByName(ifaceName) + if err != nil { + log.Fatal().Msgf("lookup network iface %q: %s", ifaceName, err) + } + + if b.Program.ProgType == models.TCType { + if err := b.UnLoadTCProgram(ifaceName, direction); err != nil { + log.Warn().Msgf("UnloadTC program failed iface %q direction %s error - %v", ifaceName, direction, err) + } + } + + if b.CollectionRef != nil { + b.CollectionRef.Close() + } + + // remove pinned map file + if err := b.RemoveMapFile(); err != nil { + log.Error().Msgf("failed to remove map file for program %s => %s", ifaceName, b.Program.Name) + } + + return nil +} + +func (b *BPF) UnLoadTCProgram(ifaceName, direction string) error { + + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + log.Fatal().Msgf("lookup network iface %q: %s", ifaceName, err) + } + + bpfRootProg := b.CollectionRef.Programs[b.Program.EntryFunctionName] + + var parent uint32 + if direction == models.IngressType { + parent = tc.HandleMinIngress + } else if direction == models.EgressType { + parent = tc.HandleMinEgress + } + + tcfilts, err := b.TCFilter.Get(&tc.Msg{ + Family: unix.AF_UNSPEC, + Ifindex: uint32(iface.Index), + Handle: 0x0, + Parent: core.BuildHandle(tc.HandleRoot, tc.HandleMinIngress), + }) + + if err != nil { + log.Warn().Msgf("Could not get filters for interface %s direction %s ", ifaceName, direction) + return fmt.Errorf("could not get filters %v", err) + } + + progFD := uint32(bpfRootProg.FD()) + bpfFlag := uint32(0x1) + filter := tc.Object{ + Msg: tc.Msg{ + Family: unix.AF_UNSPEC, + Ifindex: uint32(iface.Index), + Handle: 0, + Parent: core.BuildHandle(tc.HandleRoot, parent), + Info: tcfilts[0].Msg.Info, + }, + Attribute: tc.Attribute{ + Kind: "bpf", + BPF: &tc.Bpf{ + FD: &progFD, + Flags: &bpfFlag, + }, + }, + } + + // Detaching / Deleting filter + if err := b.TCFilter.Delete(&filter); err != nil { + return fmt.Errorf("could not dettach filter : %v", err) + } + + return nil +} + +func (b *BPF) RemoveMapFile() error { + if err := os.RemoveAll(b.MapNamePath); os.IsNotExist(err) { + log.Info().Msgf("RemoveMapFile: map file removed successfully - %s ", b.MapNamePath) + return nil + } + return nil +} + func ValidatePath(filePath string, destination string) (string, error) { destpath := filepath.Join(destination, filePath) if strings.Contains(filePath, "..") { diff --git a/kf/nfconfig.go b/kf/nfconfig.go index dcf21623..fc203d57 100644 --- a/kf/nfconfig.go +++ b/kf/nfconfig.go @@ -378,7 +378,7 @@ func (c *NFConfigs) VerifyNUpdateBPFProgram(bpfProg *models.BPFProgram, ifaceNam // update if not a last program if e.Next() != nil { - data.PutNextProgFDFromID(e.Next().Value.(*BPF).ProgID) + data.PutNextProgFDFromID(int(e.Next().Value.(*BPF).ProgID)) } return nil @@ -599,7 +599,7 @@ func (c *NFConfigs) StopRootProgram(ifaceName, direction string) error { func (c *NFConfigs) LinkBPFPrograms(leftBPF, rightBPF *BPF) error { log.Info().Msgf("LinkBPFPrograms : left BPF Prog %s right BPF Prog %s", leftBPF.Program.Name, rightBPF.Program.Name) rightBPF.PrevMapNamePath = leftBPF.MapNamePath - if err := leftBPF.PutNextProgFDFromID(rightBPF.ProgID); err != nil { + if err := leftBPF.PutNextProgFDFromID(int(rightBPF.ProgID)); err != nil { log.Error().Err(err).Msgf("LinkBPFPrograms - failed to update program fd in prev prog map before move") return fmt.Errorf("LinkBPFPrograms - failed to update program fd in prev prog prog map before move %v", err) }