diff --git a/charts/kube-ovn/templates/ovn-CR.yaml b/charts/kube-ovn/templates/ovn-CR.yaml index 54e69a5b6e3..77868d4b688 100644 --- a/charts/kube-ovn/templates/ovn-CR.yaml +++ b/charts/kube-ovn/templates/ovn-CR.yaml @@ -210,6 +210,7 @@ rules: - ovn-eips/status - nodes - pods + - vlans verbs: - get - list diff --git a/dist/images/install.sh b/dist/images/install.sh index 7bc3ac36740..aef6f5affa6 100755 --- a/dist/images/install.sh +++ b/dist/images/install.sh @@ -3076,6 +3076,7 @@ rules: - ovn-eips/status - nodes - pods + - vlans verbs: - get - list diff --git a/go.mod b/go.mod index da07a3cb2b7..d5ddbd8db96 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 github.com/containernetworking/cni v1.1.2 github.com/containernetworking/plugins v1.4.1 + github.com/digitalocean/go-openvswitch v0.0.0-20240130171624-c0f7d42efe24 github.com/docker/docker v26.0.2+incompatible github.com/emicklei/go-restful/v3 v3.12.0 github.com/evanphx/json-patch/v5 v5.9.0 diff --git a/go.sum b/go.sum index aa48e9b273f..ef71cba05f2 100644 --- a/go.sum +++ b/go.sum @@ -713,6 +713,7 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -773,6 +774,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/go-openvswitch v0.0.0-20240130171624-c0f7d42efe24 h1:TmvrZSP2gKAIYHq02BofeGXG3rPIIkNQjie5gN1pQ9M= +github.com/digitalocean/go-openvswitch v0.0.0-20240130171624-c0f7d42efe24/go.mod h1:OAtI/pEmN/EvxlkixiYp2nMQQEtEqzHcpWeE2AW2Bb8= github.com/docker/docker v26.0.2+incompatible h1:yGVmKUFGgcxA6PXWAokO0sQL22BrQ67cgVjko8tGdXE= github.com/docker/docker v26.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -830,6 +833,7 @@ github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -1172,10 +1176,19 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= 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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +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/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1288,9 +1301,22 @@ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvls github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE= github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118/go.mod h1:ZFUnHIVchZ9lJoWoEGUg8Q3M4U8aNNWA3CVSUTkW4og= +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/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU= github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY= github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4= +github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc= github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E= github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= @@ -1802,6 +1828,7 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1818,11 +1845,13 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +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= @@ -1932,6 +1961,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1943,11 +1973,13 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1976,12 +2008,18 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1995,6 +2033,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/daemon/controller.go b/pkg/daemon/controller.go index 5fbcbfbde15..a9ec39c7044 100644 --- a/pkg/daemon/controller.go +++ b/pkg/daemon/controller.go @@ -47,6 +47,9 @@ type Controller struct { ovnEipsLister kubeovnlister.OvnEipLister ovnEipsSynced cache.InformerSynced + vlansLister kubeovnlister.VlanLister + vlanSynced cache.InformerSynced + podsLister listerv1.PodLister podsSynced cache.InformerSynced podQueue workqueue.RateLimitingInterface @@ -75,6 +78,7 @@ func NewController(config *Configuration, stopCh <-chan struct{}, podInformerFac providerNetworkInformer := kubeovnInformerFactory.Kubeovn().V1().ProviderNetworks() subnetInformer := kubeovnInformerFactory.Kubeovn().V1().Subnets() ovnEipInformer := kubeovnInformerFactory.Kubeovn().V1().OvnEips() + vlanInformer := kubeovnInformerFactory.Kubeovn().V1().Vlans() podInformer := podInformerFactory.Core().V1().Pods() nodeInformer := nodeInformerFactory.Core().V1().Nodes() @@ -93,6 +97,9 @@ func NewController(config *Configuration, stopCh <-chan struct{}, podInformerFac ovnEipsLister: ovnEipInformer.Lister(), ovnEipsSynced: ovnEipInformer.Informer().HasSynced, + vlansLister: vlanInformer.Lister(), + vlanSynced: vlanInformer.Informer().HasSynced, + podsLister: podInformer.Lister(), podsSynced: podInformer.Informer().HasSynced, podQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Pod"), @@ -120,7 +127,7 @@ func NewController(config *Configuration, stopCh <-chan struct{}, podInformerFac if !cache.WaitForCacheSync(stopCh, controller.providerNetworksSynced, controller.subnetsSynced, - controller.podsSynced, controller.nodesSynced) { + controller.podsSynced, controller.nodesSynced, controller.vlanSynced) { util.LogFatalAndExit(nil, "failed to wait for caches to sync") } diff --git a/pkg/daemon/controller_linux.go b/pkg/daemon/controller_linux.go index 705ad59ec83..f8cb3a983a8 100644 --- a/pkg/daemon/controller_linux.go +++ b/pkg/daemon/controller_linux.go @@ -10,10 +10,12 @@ import ( "path/filepath" "reflect" "regexp" + "slices" "strings" "syscall" "github.com/alauda/felix/ipsets" + ovsutil "github.com/digitalocean/go-openvswitch/ovs" "github.com/kubeovn/go-iptables/iptables" "github.com/vishvananda/netlink" v1 "k8s.io/api/core/v1" @@ -39,7 +41,8 @@ type ControllerRuntime struct { ipsets map[string]*ipsets.IPSets gwCounters map[string]*util.GwIPtableCounters - nmSyncer *networkManagerSyncer + nmSyncer *networkManagerSyncer + ovsClient *ovsutil.Client } func evalCommandSymlinks(cmd string) (string, error) { @@ -83,6 +86,7 @@ func (c *Controller) initRuntime() error { c.gwCounters = make(map[string]*util.GwIPtableCounters) c.k8siptables = make(map[string]k8siptables.Interface) c.k8sipsets = k8sipset.New(c.k8sExec) + c.ovsClient = ovsutil.New() if c.protocol == kubeovnv1.ProtocolIPv4 || c.protocol == kubeovnv1.ProtocolDual { ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) @@ -184,6 +188,78 @@ func (c *Controller) reconcileRouters(event *subnetEvent) error { return err } } + + // u2o arp filter in underlay subnet bridge to avoid arp request to u2o IP + if newSubnet != nil && newSubnet.Spec.Vlan != "" && !newSubnet.Spec.LogicalGateway { + vlanName := newSubnet.Spec.Vlan + vlan, err := c.vlansLister.Get(vlanName) + if err != nil { + klog.Errorf("failed to get vlan %s %v", vlanName, err) + return err + } + pn, err := c.providerNetworksLister.Get(vlan.Spec.Provider) + if err != nil { + klog.Errorf("failed to get provider network %s %v", vlan.Spec.Provider, err) + return err + } + + if pn.Status.Ready { + bridgeName := util.ExternalBridgeName(pn.Name) + underlayNic := pn.Spec.DefaultInterface + for _, item := range pn.Spec.CustomInterfaces { + if slices.Contains(item.Nodes, c.config.NodeName) { + underlayNic = item.Interface + break + } + } + + if newSubnet.Status.U2OInterconnectionIP != "" { + u2oIPs := strings.Split(newSubnet.Status.U2OInterconnectionIP, ",") + gatewayIPs := strings.Split(newSubnet.Spec.Gateway, ",") + + if len(u2oIPs) != len(gatewayIPs) { + err := fmt.Errorf("u2o interconnection IPs %v and gateway IPs %v are not matched", u2oIPs, gatewayIPs) + klog.Error(err) + return err + + } + for index, u2oIP := range u2oIPs { + err := ovs.AddOrUpdateU2OFilterOpenFlow(c.ovsClient, bridgeName, gatewayIPs[index], u2oIP, underlayNic) + if err != nil { + return err + } + } + } else { + err := ovs.DeleteAllU2OFilterOpenFlow(c.ovsClient, bridgeName, newSubnet.Spec.Protocol) + if err != nil { + return err + } + } + } + } + + // remove subnet need remove u2o filter openflow + if newSubnet == nil && oldSubnet.Spec.Vlan != "" && !oldSubnet.Spec.LogicalGateway { + vlanName := oldSubnet.Spec.Vlan + vlan, err := c.vlansLister.Get(vlanName) + if err != nil { + klog.Errorf("failed to get vlan %s %v", vlanName, err) + return err + } + pn, err := c.providerNetworksLister.Get(vlan.Spec.Provider) + if err != nil { + klog.Errorf("failed to get provider network %s %v", vlan.Spec.Provider, err) + return err + } + + if pn.Status.Ready { + bridgeName := util.ExternalBridgeName(pn.Name) + err = ovs.DeleteAllU2OFilterOpenFlow(c.ovsClient, bridgeName, oldSubnet.Spec.Protocol) + if err != nil { + return err + } + } + } } node, err := c.nodesLister.Get(c.config.NodeName) diff --git a/pkg/ovs/ovs-ofctl.go b/pkg/ovs/ovs-ofctl.go new file mode 100644 index 00000000000..b15416f36de --- /dev/null +++ b/pkg/ovs/ovs-ofctl.go @@ -0,0 +1,140 @@ +package ovs + +import ( + "github.com/digitalocean/go-openvswitch/ovs" + "k8s.io/klog/v2" + + kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" + "github.com/kubeovn/kube-ovn/pkg/util" +) + +func AddOrUpdateU2OFilterOpenFlow(client *ovs.Client, bridgeName, gatewayIP, u2oIP, underlayNic string) error { + isIPv6 := false + if util.CheckProtocol(gatewayIP) == kubeovnv1.ProtocolIPv6 { + isIPv6 = true + } + var match *ovs.MatchFlow + var flow *ovs.Flow + var inPortID int + + portInfo, err := client.OpenFlow.DumpPort(bridgeName, underlayNic) + if err != nil { + klog.Errorf("failed to dump bridge %s port %s: %v", bridgeName, underlayNic, err) + return err + } + inPortID = portInfo.PortID + klog.V(3).Infof(" underlayNic %s's portID is %d", underlayNic, inPortID) + + if isIPv6 { + match = &ovs.MatchFlow{ + Protocol: ovs.ProtocolICMPv6, + InPort: inPortID, + Matches: []ovs.Match{ + ovs.ICMP6Type(135), + ovs.NeighborDiscoveryTarget(u2oIP), + }, + Cookie: util.U2OFilterOpenFlowCookieV6, + } + // ovs-ofctl add-flow {underlay bridge} "cookie=0x1001,table=0,priority=10000,in_port=1,icmp6,icmp_type=135,nd_target={u2oIP},actions=drop" + flow = &ovs.Flow{ + Priority: util.U2OFilterOpenFlowPriority, + Protocol: ovs.ProtocolICMPv6, + InPort: inPortID, + Matches: []ovs.Match{ + ovs.ICMP6Type(135), + ovs.NeighborDiscoveryTarget(u2oIP), + }, + Cookie: util.U2OFilterOpenFlowCookieV6, + Actions: []ovs.Action{ovs.Drop()}, + } + } else { + match = &ovs.MatchFlow{ + Protocol: ovs.ProtocolARP, + InPort: inPortID, + Matches: []ovs.Match{ + ovs.ARPSourceProtocolAddress(gatewayIP), + ovs.ARPTargetProtocolAddress(u2oIP), + ovs.ARPOperation(1), + }, + Cookie: util.U2OFilterOpenFlowCookieV4, + } + // ovs-ofctl add-flow {underlay bridge} "cookie=0x1000,table=0,priority=10000,in_port=1,arp,arp_spa={gatewayIP},arp_tpa={u2oIP},arp_op=1,actions=drop" + flow = &ovs.Flow{ + Priority: util.U2OFilterOpenFlowPriority, + Protocol: ovs.ProtocolARP, + InPort: inPortID, + Matches: []ovs.Match{ + ovs.ARPSourceProtocolAddress(gatewayIP), + ovs.ARPTargetProtocolAddress(u2oIP), + ovs.ARPOperation(1), // ARP Request + }, + Cookie: util.U2OFilterOpenFlowCookieV4, + Actions: []ovs.Action{ovs.Drop()}, + } + } + + flows, err := client.OpenFlow.DumpFlowsWithFlowArgs(bridgeName, match) + if err != nil { + klog.Errorf("failed to dump flows: %v", err) + return err + } + + // check if the target flow already exist, if exist return + if len(flows) > 0 { + return nil + } + + // check if any gc flow exist, if exist remove it + if err := delU2OFilterOpenFlow(client, bridgeName, isIPv6); err != nil { + return err + } + + klog.Infof("add bridge %s u2o filter openflow rule", bridgeName) + err = client.OpenFlow.AddFlow(bridgeName, flow) + if err != nil { + return err + } + + return nil +} + +func DeleteAllU2OFilterOpenFlow(client *ovs.Client, bridgeName, protocol string) error { + if protocol == kubeovnv1.ProtocolIPv4 || protocol == kubeovnv1.ProtocolDual { + if err := delU2OFilterOpenFlow(client, bridgeName, false); err != nil { + return err + } + } + if protocol == kubeovnv1.ProtocolIPv6 || protocol == kubeovnv1.ProtocolDual { + if err := delU2OFilterOpenFlow(client, bridgeName, true); err != nil { + return err + } + } + return nil +} + +func delU2OFilterOpenFlow(client *ovs.Client, bridgeName string, isV6 bool) error { + cookie := util.U2OFilterOpenFlowCookieV4 + if isV6 { + cookie = util.U2OFilterOpenFlowCookieV6 + } + + match := &ovs.MatchFlow{ + Cookie: uint64(cookie), + } + + oldflows, err := client.OpenFlow.DumpFlowsWithFlowArgs(bridgeName, match) + if err != nil { + klog.Errorf("failed to dump flows: %v", err) + return err + } + + if len(oldflows) > 0 { + klog.Infof("remove bridge %s old u2o filter openflow rule", bridgeName) + err = client.OpenFlow.DelFlows(bridgeName, match) + if err != nil { + klog.Errorf("failed to remove old u2o filter openflow rule: %v", err) + return err + } + } + return nil +} diff --git a/pkg/util/const.go b/pkg/util/const.go index d7862278c62..f9516dd5b8a 100644 --- a/pkg/util/const.go +++ b/pkg/util/const.go @@ -279,4 +279,8 @@ const ( TProxyPreroutingMask = 0x90004 HealthCheckNamedVipTemplate = "%s:%s" // ip name, health check vip + + U2OFilterOpenFlowPriority = 10000 + U2OFilterOpenFlowCookieV4 = 0x1000 + U2OFilterOpenFlowCookieV6 = 0x1001 )