)]}'
{"metropolis/node/core/localstorage/storage.go":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":168,"context_line":"\tRunSCLogsFIFO declarative.File      `file:\"runsc-logs.fifo\"`"},{"line_number":169,"context_line":"\tTmp           declarative.Directory `dir:\"tmp\"`"},{"line_number":170,"context_line":"\tRunSC         declarative.Directory `dir:\"runsc\"`"},{"line_number":171,"context_line":"\tIPAM          declarative.Directory `dir:\"ipam\"`"},{"line_number":172,"context_line":"\tCNI           declarative.Directory `dir:\"cni\"`"},{"line_number":173,"context_line":"}"},{"line_number":174,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"e7ac1a0c_95715496","line":171,"updated":"2025-08-07 16:17:35.000000000","message":"ipam and cni are also no longer needed.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":168,"context_line":"\tRunSCLogsFIFO declarative.File      `file:\"runsc-logs.fifo\"`"},{"line_number":169,"context_line":"\tTmp           declarative.Directory `dir:\"tmp\"`"},{"line_number":170,"context_line":"\tRunSC         declarative.Directory `dir:\"runsc\"`"},{"line_number":171,"context_line":"\tIPAM          declarative.Directory `dir:\"ipam\"`"},{"line_number":172,"context_line":"\tCNI           declarative.Directory `dir:\"cni\"`"},{"line_number":173,"context_line":"}"},{"line_number":174,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"455bd83f_1704acc4","line":171,"in_reply_to":"e7ac1a0c_95715496","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"}],"metropolis/node/core/network/main.go":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":79,"context_line":"\t}"},{"line_number":80,"context_line":"}"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"// Status is the current network status of the host. It will be updated by the"},{"line_number":83,"context_line":"// network Service whenever the node\u0027s network configuration changes. Spurious"},{"line_number":84,"context_line":"// changes might occur, consumers should ensure that the change that occured is"},{"line_number":85,"context_line":"// meaningful to them."}],"source_content_type":"text/x-go","patch_set":1,"id":"a7eee762_80a9169f","side":"PARENT","line":82,"updated":"2025-08-07 16:17:35.000000000","message":"This should be removed in the previous commit instead.","commit_id":"b46fc48b3942a9df55d387bad13ccd3a7fba05c3"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":79,"context_line":"\t}"},{"line_number":80,"context_line":"}"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"// Status is the current network status of the host. It will be updated by the"},{"line_number":83,"context_line":"// network Service whenever the node\u0027s network configuration changes. Spurious"},{"line_number":84,"context_line":"// changes might occur, consumers should ensure that the change that occured is"},{"line_number":85,"context_line":"// meaningful to them."}],"source_content_type":"text/x-go","patch_set":1,"id":"6f57eed9_cb423738","side":"PARENT","line":82,"in_reply_to":"a7eee762_80a9169f","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"b46fc48b3942a9df55d387bad13ccd3a7fba05c3"}],"metropolis/node/core/network/workloads/spec/workload.proto":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"message StatusRequest {}"},{"line_number":42,"context_line":"message StatusResponse {"},{"line_number":43,"context_line":"    bool ready \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"}],"source_content_type":"text/x-protobuf","patch_set":3,"id":"47057dc7_046151a7","line":43,"updated":"2025-08-07 16:17:35.000000000","message":"You could remove the ready field and instead return an error when not ready. The error message can then describe why it is not ready.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"message StatusRequest {}"},{"line_number":42,"context_line":"message StatusResponse {"},{"line_number":43,"context_line":"    bool ready \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"}],"source_content_type":"text/x-protobuf","patch_set":3,"id":"e310f898_9c53af70","line":43,"in_reply_to":"47057dc7_046151a7","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"message StatusRequest {}"},{"line_number":42,"context_line":"message StatusResponse {"},{"line_number":43,"context_line":"    bool ready \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"}],"source_content_type":"text/x-protobuf","patch_set":3,"id":"12a0c980_21a9befa","line":43,"in_reply_to":"68edccc8_a6619176","updated":"2025-08-11 15:01:54.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"117dd0d843b43718c90324f674a56406905825ef","unresolved":true,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"message StatusRequest {}"},{"line_number":42,"context_line":"message StatusResponse {"},{"line_number":43,"context_line":"    bool ready \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"}],"source_content_type":"text/x-protobuf","patch_set":3,"id":"68edccc8_a6619176","line":43,"in_reply_to":"e310f898_9c53af70","updated":"2025-08-11 14:29:36.000000000","message":"What I meant is that the response message has no fields, and instead you return `status.Errorf(codes.Unavailable, \"no prefixes available\")` or similar when not ready.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"117dd0d843b43718c90324f674a56406905825ef","unresolved":true,"context_lines":[{"line_number":43,"context_line":"    string error \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"},{"line_number":47,"context_line":"    rpc Attach(AttachRequest) returns (AttachResponse);"},{"line_number":48,"context_line":"    rpc Detach(DetachRequest) returns (DetachResponse);"},{"line_number":49,"context_line":"    rpc Status(StatusRequest) returns (StatusResponse);"}],"source_content_type":"text/x-protobuf","patch_set":10,"id":"dbc311d5_b8f2f456","line":46,"updated":"2025-08-11 14:29:36.000000000","message":"I would add some documentation to describe how this service should be used, and how it should behave. Here is a suggestion:\n\n```\n// The workload networking service attaches workloads to the network.\n// The service is served over a unix socket.\n// It is called by containerd, and possibly other workload runtimes later.\n// It is a replacement for the Container Network Interface (CNI);\n// see https://github.com/containernetworking/cni/blob/main/SPEC.md\n//\n// Concurrent calls are allowed if they don\u0027t have the same workload_id.\n// For a specific workload_id, Attach may not be followed by another Attach\n// without a Detach in-between. Detach may be called multiple times.\nservice WorkloadNetworking {\n    // Attach the workload to the network. This allocates the workload IP\n    // addresses (at most one for IPv4 and IPv6), and sets up the main network\n    // interface. For network namespaces, it also enables the loopback\n    // interface.\n    rpc Attach(AttachRequest) returns (AttachResponse);\n    // Detach removes the interfaces and IP address allocation of the workload.\n    // It succeeds even if some or all resources don\u0027t exist, and removes those\n    // which do exist.\n    rpc Detach(DetachRequest) returns (DetachResponse);\n    // Status returns an error if the service is not ready.\n    rpc Status(StatusRequest) returns (StatusResponse);\n}\n```","commit_id":"bfac115c1a10739b40678465970471f8aaf9aef1"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    string error \u003d 1;"},{"line_number":44,"context_line":"}"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"service WorkloadNetworking {"},{"line_number":47,"context_line":"    rpc Attach(AttachRequest) returns (AttachResponse);"},{"line_number":48,"context_line":"    rpc Detach(DetachRequest) returns (DetachResponse);"},{"line_number":49,"context_line":"    rpc Status(StatusRequest) returns (StatusResponse);"}],"source_content_type":"text/x-protobuf","patch_set":10,"id":"6b5787ba_d5f2b45d","line":46,"in_reply_to":"dbc311d5_b8f2f456","updated":"2025-08-11 15:01:54.000000000","message":"Done","commit_id":"bfac115c1a10739b40678465970471f8aaf9aef1"}],"metropolis/node/core/network/workloads/workloads.go":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":91,"context_line":"\tfor _, a :\u003d range diskState.Attachments {"},{"line_number":92,"context_line":"\t\tip, ok :\u003d netip.AddrFromSlice(a.Ip)"},{"line_number":93,"context_line":"\t\tif !ok {"},{"line_number":94,"context_line":"\t\t\tl.Error(\"Dropping attachment for workload ID %v with bad IP (in hex) %x\", a.WorkloadId, ip)"},{"line_number":95,"context_line":"\t\t} else {"},{"line_number":96,"context_line":"\t\t\ts.attachments[ip] \u003d a.WorkloadId"},{"line_number":97,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":1,"id":"5ddaa1a3_f80e84ac","line":94,"range":{"start_line":94,"start_character":91,"end_line":94,"end_character":93},"updated":"2025-08-07 16:17:35.000000000","message":"```suggestion\n\t\t\tl.Errorf(\"Dropping attachment for workload ID %v with bad IP (in hex) %x\", a.WorkloadId, a.Ip)\n```","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":91,"context_line":"\tfor _, a :\u003d range diskState.Attachments {"},{"line_number":92,"context_line":"\t\tip, ok :\u003d netip.AddrFromSlice(a.Ip)"},{"line_number":93,"context_line":"\t\tif !ok {"},{"line_number":94,"context_line":"\t\t\tl.Error(\"Dropping attachment for workload ID %v with bad IP (in hex) %x\", a.WorkloadId, ip)"},{"line_number":95,"context_line":"\t\t} else {"},{"line_number":96,"context_line":"\t\t\ts.attachments[ip] \u003d a.WorkloadId"},{"line_number":97,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":1,"id":"f95ee76f_40561fdb","line":94,"range":{"start_line":94,"start_character":91,"end_line":94,"end_character":93},"in_reply_to":"5ddaa1a3_f80e84ac","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":155,"context_line":"\tif err !\u003d nil {"},{"line_number":156,"context_line":"\t\treturn fmt.Errorf(\"failed to listen: %w\", err)"},{"line_number":157,"context_line":"\t}"},{"line_number":158,"context_line":"\tgo srv.Serve(lis)"},{"line_number":159,"context_line":"\tgo func() {"},{"line_number":160,"context_line":"\t\t\u003c-ctx.Done()"},{"line_number":161,"context_line":"\t\tsrv.GracefulStop()"}],"source_content_type":"text/x-go","patch_set":1,"id":"efc3973a_bf1a4e86","line":158,"range":{"start_line":158,"start_character":1,"end_line":158,"end_character":18},"updated":"2025-08-07 16:17:35.000000000","message":"I would use supervisor.GRPCServer.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":155,"context_line":"\tif err !\u003d nil {"},{"line_number":156,"context_line":"\t\treturn fmt.Errorf(\"failed to listen: %w\", err)"},{"line_number":157,"context_line":"\t}"},{"line_number":158,"context_line":"\tgo srv.Serve(lis)"},{"line_number":159,"context_line":"\tgo func() {"},{"line_number":160,"context_line":"\t\t\u003c-ctx.Done()"},{"line_number":161,"context_line":"\t\tsrv.GracefulStop()"}],"source_content_type":"text/x-go","patch_set":1,"id":"04268cc1_641563c9","line":158,"range":{"start_line":158,"start_character":1,"end_line":158,"end_character":18},"in_reply_to":"efc3973a_bf1a4e86","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":167,"context_line":"\tif err !\u003d nil {"},{"line_number":168,"context_line":"\t\tpanic(err)"},{"line_number":169,"context_line":"\t}"},{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"}],"source_content_type":"text/x-go","patch_set":1,"id":"4a3aed4f_806cbde3","line":170,"updated":"2025-08-07 16:17:35.000000000","message":"If the service restarts, this will fail with \"Unable to add router IP: file exists\". You could suppress this error with `!errors.Is(err, unix.EEXIST)`.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":167,"context_line":"\tif err !\u003d nil {"},{"line_number":168,"context_line":"\t\tpanic(err)"},{"line_number":169,"context_line":"\t}"},{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"}],"source_content_type":"text/x-go","patch_set":1,"id":"2cfa34e2_81113507","line":170,"in_reply_to":"4a3aed4f_806cbde3","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":168,"context_line":"\t\tpanic(err)"},{"line_number":169,"context_line":"\t}"},{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"},{"line_number":174,"context_line":"\t\tScope: unix.RT_SCOPE_LINK,"}],"source_content_type":"text/x-go","patch_set":1,"id":"cb25c18f_3b291991","line":171,"range":{"start_line":171,"start_character":24,"end_line":171,"end_character":49},"updated":"2025-08-07 16:17:35.000000000","message":"Replace with firstHopV4.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":168,"context_line":"\t\tpanic(err)"},{"line_number":169,"context_line":"\t}"},{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"},{"line_number":174,"context_line":"\t\tScope: unix.RT_SCOPE_LINK,"}],"source_content_type":"text/x-go","patch_set":1,"id":"235d174f_7905ec6d","line":171,"range":{"start_line":171,"start_character":24,"end_line":171,"end_character":49},"in_reply_to":"cb25c18f_3b291991","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"},{"line_number":174,"context_line":"\t\tScope: unix.RT_SCOPE_LINK,"},{"line_number":175,"context_line":"\t}); err !\u003d nil {"},{"line_number":176,"context_line":"\t\tl.Errorf(\"Unable to add router IP: %v\", err)"}],"source_content_type":"text/x-go","patch_set":1,"id":"09b33461_dcf01a76","line":173,"range":{"start_line":173,"start_character":2,"end_line":173,"end_character":30},"updated":"2025-08-07 16:17:35.000000000","message":"This doesn\u0027t work, because the kernel ignores this flag coming from user space and instead derives it from prefered_lft.\nhttps://elixir.bootlin.com/linux/v6.16/source/net/ipv4/devinet.c#L825\n\nTo mark the address as deprecated, you instead need to set `ValidLft: math.MaxUint32,`. This way, you set the valid lifetime to infinity and the prefered lifetime to 0, so it\u0027s immediately deprecated.\n\nBut as far as I can tell, marking an address as deprecated has no effect for IPv4.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":170,"context_line":"\tif err :\u003d netlink.AddrAdd(lo, \u0026netlink.Addr{"},{"line_number":171,"context_line":"\t\tIPNet: \u0026net.IPNet{IP: net.IPv4(169, 254, 77, 1), Mask: net.CIDRMask(32, 32)},"},{"line_number":172,"context_line":"\t\tLabel: \"Router\","},{"line_number":173,"context_line":"\t\tFlags: unix.IFA_F_DEPRECATED, // Just a next-hop, do not use for IP routing"},{"line_number":174,"context_line":"\t\tScope: unix.RT_SCOPE_LINK,"},{"line_number":175,"context_line":"\t}); err !\u003d nil {"},{"line_number":176,"context_line":"\t\tl.Errorf(\"Unable to add router IP: %v\", err)"}],"source_content_type":"text/x-go","patch_set":1,"id":"160ec3cf_6e3be674","line":173,"range":{"start_line":173,"start_character":2,"end_line":173,"end_character":30},"in_reply_to":"09b33461_dcf01a76","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":187,"context_line":"\t\t\treturn err"},{"line_number":188,"context_line":"\t\t}"},{"line_number":189,"context_line":"\t\tif prefixes !\u003d nil {"},{"line_number":190,"context_line":"\t\t\tl.Infof(\"Got new workload nets: %v\", prefixes)"},{"line_number":191,"context_line":"\t\t\ts.mux.Lock()"},{"line_number":192,"context_line":"\t\t\ts.workloadNets \u003d *prefixes"},{"line_number":193,"context_line":"\t\t\ts.mux.Unlock()"}],"source_content_type":"text/x-go","patch_set":1,"id":"bd1e8249_3a8df9ea","line":190,"range":{"start_line":190,"start_character":12,"end_line":190,"end_character":33},"updated":"2025-08-07 16:17:35.000000000","message":"This spams the log every few seconds. Because this is going away soon, I would just remove the log.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":187,"context_line":"\t\t\treturn err"},{"line_number":188,"context_line":"\t\t}"},{"line_number":189,"context_line":"\t\tif prefixes !\u003d nil {"},{"line_number":190,"context_line":"\t\t\tl.Infof(\"Got new workload nets: %v\", prefixes)"},{"line_number":191,"context_line":"\t\t\ts.mux.Lock()"},{"line_number":192,"context_line":"\t\t\ts.workloadNets \u003d *prefixes"},{"line_number":193,"context_line":"\t\t\ts.mux.Unlock()"}],"source_content_type":"text/x-go","patch_set":1,"id":"912e7b87_f7237051","line":190,"range":{"start_line":190,"start_character":12,"end_line":190,"end_character":33},"in_reply_to":"bd1e8249_3a8df9ea","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"\tlinkAttrs :\u003d netlink.NewLinkAttrs()"},{"line_number":205,"context_line":"\tlinkAttrs.Group \u003d node.LinkGroupK8sPod"},{"line_number":206,"context_line":"\tlinkAttrs.Name \u003d \"wl\" + req.WorkloadId[:13]"},{"line_number":207,"context_line":"\tlinkAttrs.HardwareAddr \u003d firstHopMAC"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"}],"source_content_type":"text/x-go","patch_set":1,"id":"fab5b09a_24069ec9","line":206,"range":{"start_line":206,"start_character":19,"end_line":206,"end_character":21},"updated":"2025-08-07 16:17:35.000000000","message":"The \"wl\" prefix is commonly used for wireless interfaces. Maybe use \"wk\" instead?","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"\tlinkAttrs :\u003d netlink.NewLinkAttrs()"},{"line_number":205,"context_line":"\tlinkAttrs.Group \u003d node.LinkGroupK8sPod"},{"line_number":206,"context_line":"\tlinkAttrs.Name \u003d \"wl\" + req.WorkloadId[:13]"},{"line_number":207,"context_line":"\tlinkAttrs.HardwareAddr \u003d firstHopMAC"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"}],"source_content_type":"text/x-go","patch_set":1,"id":"30a80ce0_0cb9acee","line":206,"range":{"start_line":206,"start_character":19,"end_line":206,"end_character":21},"in_reply_to":"fab5b09a_24069ec9","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":267,"context_line":""},{"line_number":268,"context_line":"\t\tif err :\u003d nsHandle.AddrAdd(workloadIf, \u0026netlink.Addr{"},{"line_number":269,"context_line":"\t\t\tIPNet:     \u0026net.IPNet{IP: workloadIP, Mask: hostMask},"},{"line_number":270,"context_line":"\t\t\tLinkIndex: workloadIf.Attrs().Index,"},{"line_number":271,"context_line":"\t\t}); err !\u003d nil {"},{"line_number":272,"context_line":"\t\t\treturn nil, fmt.Errorf(\"failed to add address: %w\", err)"},{"line_number":273,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":1,"id":"256bff69_a7581f6e","line":270,"range":{"start_line":270,"start_character":3,"end_line":270,"end_character":39},"updated":"2025-08-07 16:17:35.000000000","message":"This line is not needed, because you already pass workloadIf in the first parameter and it takes the link index from that.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":267,"context_line":""},{"line_number":268,"context_line":"\t\tif err :\u003d nsHandle.AddrAdd(workloadIf, \u0026netlink.Addr{"},{"line_number":269,"context_line":"\t\t\tIPNet:     \u0026net.IPNet{IP: workloadIP, Mask: hostMask},"},{"line_number":270,"context_line":"\t\t\tLinkIndex: workloadIf.Attrs().Index,"},{"line_number":271,"context_line":"\t\t}); err !\u003d nil {"},{"line_number":272,"context_line":"\t\t\treturn nil, fmt.Errorf(\"failed to add address: %w\", err)"},{"line_number":273,"context_line":"\t\t}"}],"source_content_type":"text/x-go","patch_set":1,"id":"855d47f6_fb96688b","line":270,"range":{"start_line":270,"start_character":3,"end_line":270,"end_character":39},"in_reply_to":"256bff69_a7581f6e","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":282,"context_line":"\t\t\treturn nil, fmt.Errorf(\"failed to add peer route: %w\", err)"},{"line_number":283,"context_line":"\t\t}"},{"line_number":284,"context_line":"\t\tif err :\u003d nsHandle.RouteAdd(\u0026netlink.Route{"},{"line_number":285,"context_line":"\t\t\tDst:       \u0026net.IPNet{IP: net.IPv4zero, Mask: defaultMask},"},{"line_number":286,"context_line":"\t\t\tGw:        firstHop,"},{"line_number":287,"context_line":"\t\t\tScope:     netlink.SCOPE_UNIVERSE,"},{"line_number":288,"context_line":"\t\t\tProtocol:  unix.RTPROT_STATIC,"}],"source_content_type":"text/x-go","patch_set":1,"id":"9ae4cd7e_11f6207c","line":285,"range":{"start_line":285,"start_character":33,"end_line":285,"end_character":41},"updated":"2025-08-07 16:17:35.000000000","message":"Should use IPv6zero for IPv6.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":282,"context_line":"\t\t\treturn nil, fmt.Errorf(\"failed to add peer route: %w\", err)"},{"line_number":283,"context_line":"\t\t}"},{"line_number":284,"context_line":"\t\tif err :\u003d nsHandle.RouteAdd(\u0026netlink.Route{"},{"line_number":285,"context_line":"\t\t\tDst:       \u0026net.IPNet{IP: net.IPv4zero, Mask: defaultMask},"},{"line_number":286,"context_line":"\t\t\tGw:        firstHop,"},{"line_number":287,"context_line":"\t\t\tScope:     netlink.SCOPE_UNIVERSE,"},{"line_number":288,"context_line":"\t\t\tProtocol:  unix.RTPROT_STATIC,"}],"source_content_type":"text/x-go","patch_set":1,"id":"370e4f77_99d8637f","line":285,"range":{"start_line":285,"start_character":33,"end_line":285,"end_character":41},"in_reply_to":"9ae4cd7e_11f6207c","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":333,"context_line":""},{"line_number":334,"context_line":"func (s *Service) Status(ctx context.Context, req *wlapi.StatusRequest) (*wlapi.StatusResponse, error) {"},{"line_number":335,"context_line":"\treturn \u0026wlapi.StatusResponse{"},{"line_number":336,"context_line":"\t\tReady: len(s.workloadNets) \u003e 0,"},{"line_number":337,"context_line":"\t}, nil"},{"line_number":338,"context_line":"}"}],"source_content_type":"text/x-go","patch_set":1,"id":"180d6551_3cb8b30d","line":336,"range":{"start_line":336,"start_character":13,"end_line":336,"end_character":27},"updated":"2025-08-07 16:17:35.000000000","message":"Acquire the mutex to avoid a race on s.workloadNets.","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":333,"context_line":""},{"line_number":334,"context_line":"func (s *Service) Status(ctx context.Context, req *wlapi.StatusRequest) (*wlapi.StatusResponse, error) {"},{"line_number":335,"context_line":"\treturn \u0026wlapi.StatusResponse{"},{"line_number":336,"context_line":"\t\tReady: len(s.workloadNets) \u003e 0,"},{"line_number":337,"context_line":"\t}, nil"},{"line_number":338,"context_line":"}"}],"source_content_type":"text/x-go","patch_set":1,"id":"dae5c387_45e8ed8c","line":336,"range":{"start_line":336,"start_character":13,"end_line":336,"end_character":27},"in_reply_to":"180d6551_3cb8b30d","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"3eeb11d393d0245d82498efdd99ff4c5cf278585"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":80,"context_line":"\t\treturn"},{"line_number":81,"context_line":"\t}"},{"line_number":82,"context_line":"\tif err !\u003d nil {"},{"line_number":83,"context_line":"\t\tl.Errorf(\"Unable to read previous wlnet state, ignoring: %w\", err)"},{"line_number":84,"context_line":"\t\treturn"},{"line_number":85,"context_line":"\t}"},{"line_number":86,"context_line":"\tvar diskState wlapi.State"}],"source_content_type":"text/x-go","patch_set":3,"id":"83cdf395_db8916fb","line":83,"range":{"start_line":83,"start_character":59,"end_line":83,"end_character":61},"updated":"2025-08-07 16:17:35.000000000","message":"`%w` can\u0027t be used with logger.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":80,"context_line":"\t\treturn"},{"line_number":81,"context_line":"\t}"},{"line_number":82,"context_line":"\tif err !\u003d nil {"},{"line_number":83,"context_line":"\t\tl.Errorf(\"Unable to read previous wlnet state, ignoring: %w\", err)"},{"line_number":84,"context_line":"\t\treturn"},{"line_number":85,"context_line":"\t}"},{"line_number":86,"context_line":"\tvar diskState wlapi.State"}],"source_content_type":"text/x-go","patch_set":3,"id":"dd26dfed_34d5b5db","line":83,"range":{"start_line":83,"start_character":59,"end_line":83,"end_character":61},"in_reply_to":"83cdf395_db8916fb","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":146,"context_line":""},{"line_number":147,"context_line":"func (s *Service) Run(ctx context.Context) error {"},{"line_number":148,"context_line":"\tl :\u003d supervisor.Logger(ctx)"},{"line_number":149,"context_line":"\ts.load(ctx)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"\tsrv :\u003d grpc.NewServer()"},{"line_number":152,"context_line":"\twlapi.RegisterWorkloadNetworkingServer(srv, s)"}],"source_content_type":"text/x-go","patch_set":3,"id":"07203931_03b02e2e","line":149,"range":{"start_line":149,"start_character":1,"end_line":149,"end_character":12},"updated":"2025-08-07 16:17:35.000000000","message":"Is this intended to keep IP address assignments across reboot? If not, why even have this file? If yes, this doesn\u0027t work for multiple reasons:\n\nThis fails to load the file after a reboot. The /data partition is only mounted once the node has joined the cluster, but the service is started before that. You\u0027d have to wait for the partition to be mounted before loading the file.\n\nAfter a reboot, containerd will first call Remove before calling Add again. If you delete the address assignment on Remove, that means we still assign new addresses after a reboot. If you want to keep the assignment the same, then we can\u0027t delete it when containerd calls Remove, and instead track when Kubernetes pods are deleted ourselves.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":146,"context_line":""},{"line_number":147,"context_line":"func (s *Service) Run(ctx context.Context) error {"},{"line_number":148,"context_line":"\tl :\u003d supervisor.Logger(ctx)"},{"line_number":149,"context_line":"\ts.load(ctx)"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"\tsrv :\u003d grpc.NewServer()"},{"line_number":152,"context_line":"\twlapi.RegisterWorkloadNetworkingServer(srv, s)"}],"source_content_type":"text/x-go","patch_set":3,"id":"51611349_8b9887f6","line":149,"range":{"start_line":149,"start_character":1,"end_line":149,"end_character":12},"in_reply_to":"07203931_03b02e2e","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":151,"context_line":"\tsrv :\u003d grpc.NewServer()"},{"line_number":152,"context_line":"\twlapi.RegisterWorkloadNetworkingServer(srv, s)"},{"line_number":153,"context_line":"\tos.Remove(\"/ephemeral/wlapi.sock\")"},{"line_number":154,"context_line":"\tlis, err :\u003d net.ListenUnix(\"unix\", \u0026net.UnixAddr{Net: \"unix\", Name: \"/ephemeral/wlapi.sock\"})"},{"line_number":155,"context_line":"\tif err !\u003d nil {"},{"line_number":156,"context_line":"\t\treturn fmt.Errorf(\"failed to listen: %w\", err)"},{"line_number":157,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":3,"id":"e7734f0e_7809e896","line":154,"range":{"start_line":154,"start_character":81,"end_line":154,"end_character":91},"updated":"2025-08-07 16:17:35.000000000","message":"This name is not descriptive, it doesn\u0027t even mention that this is about network. Suggestion: \"workloadnet.sock\"","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":151,"context_line":"\tsrv :\u003d grpc.NewServer()"},{"line_number":152,"context_line":"\twlapi.RegisterWorkloadNetworkingServer(srv, s)"},{"line_number":153,"context_line":"\tos.Remove(\"/ephemeral/wlapi.sock\")"},{"line_number":154,"context_line":"\tlis, err :\u003d net.ListenUnix(\"unix\", \u0026net.UnixAddr{Net: \"unix\", Name: \"/ephemeral/wlapi.sock\"})"},{"line_number":155,"context_line":"\tif err !\u003d nil {"},{"line_number":156,"context_line":"\t\treturn fmt.Errorf(\"failed to listen: %w\", err)"},{"line_number":157,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":3,"id":"b98e323c_9e806dbf","line":154,"range":{"start_line":154,"start_character":81,"end_line":154,"end_character":91},"in_reply_to":"e7734f0e_7809e896","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"\tlinkAttrs :\u003d netlink.NewLinkAttrs()"},{"line_number":205,"context_line":"\tlinkAttrs.Group \u003d node.LinkGroupK8sPod"},{"line_number":206,"context_line":"\tlinkAttrs.Name \u003d \"wl\" + req.WorkloadId[:13]"},{"line_number":207,"context_line":"\tlinkAttrs.HardwareAddr \u003d firstHopMAC"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"}],"source_content_type":"text/x-go","patch_set":3,"id":"bebd225b_792ec763","line":206,"range":{"start_line":206,"start_character":25,"end_line":206,"end_character":44},"updated":"2025-08-07 16:17:35.000000000","message":"I\u0027m not completely happy with using this prefix, this looks short enough that collisions might happen occasionally. Alternative proposal: \"wkUUUU-RRRR\" where UUUU is the first four characters of the pod UUID, and RRRR is a random hex value. Check in a loop if the name is already used, then pick a new random value.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":"\tlinkAttrs :\u003d netlink.NewLinkAttrs()"},{"line_number":205,"context_line":"\tlinkAttrs.Group \u003d node.LinkGroupK8sPod"},{"line_number":206,"context_line":"\tlinkAttrs.Name \u003d \"wl\" + req.WorkloadId[:13]"},{"line_number":207,"context_line":"\tlinkAttrs.HardwareAddr \u003d firstHopMAC"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"}],"source_content_type":"text/x-go","patch_set":3,"id":"bd03f061_3220f3e8","line":206,"range":{"start_line":206,"start_character":25,"end_line":206,"end_character":44},"in_reply_to":"bebd225b_792ec763","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":298,"context_line":"func (s *Service) Detach(ctx context.Context, req *wlapi.DetachRequest) (*wlapi.DetachResponse, error) {"},{"line_number":299,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"},{"line_number":300,"context_line":"\tif err !\u003d nil {"},{"line_number":301,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"cannot open network namespace: %v\", err)"},{"line_number":302,"context_line":"\t}"},{"line_number":303,"context_line":"\tdefer netns.Close()"},{"line_number":304,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"0557287a_092582a2","line":301,"updated":"2025-08-07 16:17:35.000000000","message":"If I create a pod, and then reboot the node, I get this repeating in the logs:\n\n```\n         k8s kubelet E \"Error syncing pod, skipping\" err\u003d\"failed to \\\"KillPodSandbox\\\" for\n                     | \\\"5de38c92-97d4-4d8d-a194-adc7310bf09e\\\" with KillPodSandboxError: \\\"rpc error: code \u003d\n                     | Unavailable desc \u003d failed to destroy network for sandbox\n                     | \\\\\\\"8e54b2648e1c2c5056379c489ed4013ef05613278c9b993f963b78aa7cfc7c90\\\\\\\": rpc error: code \u003d\n                     | Unavailable desc \u003d cannot open network namespace: no such file or directory\\\"\"\n                     | pod\u003d\"default/adminpod\" podUID\u003d\"5de38c92-97d4-4d8d-a194-adc7310bf09e\"\n```\n\nThe Detach call should attempt to delete all associated resources, and not fail or stop early if one of them does not exist.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":298,"context_line":"func (s *Service) Detach(ctx context.Context, req *wlapi.DetachRequest) (*wlapi.DetachResponse, error) {"},{"line_number":299,"context_line":"\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)"},{"line_number":300,"context_line":"\tif err !\u003d nil {"},{"line_number":301,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"cannot open network namespace: %v\", err)"},{"line_number":302,"context_line":"\t}"},{"line_number":303,"context_line":"\tdefer netns.Close()"},{"line_number":304,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"e4a4eea7_74c7cea5","line":301,"in_reply_to":"0557287a_092582a2","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":312,"context_line":"\tif errors.Is(err, os.ErrNotExist) {"},{"line_number":313,"context_line":"\t\t// CNI requires that DEL calls return success if the interface in"},{"line_number":314,"context_line":"\t\t// question does not exist."},{"line_number":315,"context_line":"\t\treturn \u0026wlapi.DetachResponse{}, nil"},{"line_number":316,"context_line":"\t}"},{"line_number":317,"context_line":"\tif err !\u003d nil {"},{"line_number":318,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"error getting interface for deletion: %v\", err)"}],"source_content_type":"text/x-go","patch_set":3,"id":"0cf9b300_f5edad15","line":315,"updated":"2025-08-07 16:17:35.000000000","message":"Don\u0027t return early, we should still try to deallocate IPs if the link doesn\u0027t exist.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":312,"context_line":"\tif errors.Is(err, os.ErrNotExist) {"},{"line_number":313,"context_line":"\t\t// CNI requires that DEL calls return success if the interface in"},{"line_number":314,"context_line":"\t\t// question does not exist."},{"line_number":315,"context_line":"\t\treturn \u0026wlapi.DetachResponse{}, nil"},{"line_number":316,"context_line":"\t}"},{"line_number":317,"context_line":"\tif err !\u003d nil {"},{"line_number":318,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"error getting interface for deletion: %v\", err)"}],"source_content_type":"text/x-go","patch_set":3,"id":"48cab989_d8f1b497","line":315,"in_reply_to":"0cf9b300_f5edad15","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"117dd0d843b43718c90324f674a56406905825ef","unresolved":true,"context_lines":[{"line_number":256,"context_line":"\t}"},{"line_number":257,"context_line":"\tdefer netns.Close()"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"\tnsHandle, err :\u003d netlink.NewHandleAt(netns, unix.NETLINK_ROUTE)"},{"line_number":260,"context_line":"\tif err !\u003d nil {"},{"line_number":261,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"unable to get ns handle: %v\", err)"},{"line_number":262,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"0278865f_3321edf5","line":259,"range":{"start_line":259,"start_character":1,"end_line":259,"end_character":9},"updated":"2025-08-11 14:29:36.000000000","message":"nsHandle is unused. You can remove the netns.GetFromPath and netlink.NewHandleAt calls.","commit_id":"204c3410c7cb231420c1cb3ba353d25de5f67e12"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":256,"context_line":"\t}"},{"line_number":257,"context_line":"\tdefer netns.Close()"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"\tnsHandle, err :\u003d netlink.NewHandleAt(netns, unix.NETLINK_ROUTE)"},{"line_number":260,"context_line":"\tif err !\u003d nil {"},{"line_number":261,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"unable to get ns handle: %v\", err)"},{"line_number":262,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"46b305b2_cca51981","line":259,"range":{"start_line":259,"start_character":1,"end_line":259,"end_character":9},"in_reply_to":"0278865f_3321edf5","updated":"2025-08-11 15:01:54.000000000","message":"Done","commit_id":"204c3410c7cb231420c1cb3ba353d25de5f67e12"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":256,"context_line":"\t}"},{"line_number":257,"context_line":"\tdefer netns.Close()"},{"line_number":258,"context_line":""},{"line_number":259,"context_line":"\tnsHandle, err :\u003d netlink.NewHandleAt(netns, unix.NETLINK_ROUTE)"},{"line_number":260,"context_line":"\tif err !\u003d nil {"},{"line_number":261,"context_line":"\t\treturn nil, status.Errorf(codes.Unavailable, \"unable to get ns handle: %v\", err)"},{"line_number":262,"context_line":"\t}"}],"source_content_type":"text/x-go","patch_set":4,"id":"c19f4548_e0f66146","line":259,"range":{"start_line":259,"start_character":1,"end_line":259,"end_character":9},"in_reply_to":"0278865f_3321edf5","updated":"2025-08-11 15:01:54.000000000","message":"Done","commit_id":"204c3410c7cb231420c1cb3ba353d25de5f67e12"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"117dd0d843b43718c90324f674a56406905825ef","unresolved":true,"context_lines":[{"line_number":268,"context_line":"\t}"},{"line_number":269,"context_line":"\tdefer nsHandle.Close()"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"\thostIf, err :\u003d netlink.LinkByAlias(\"wk\" + req.WorkloadId)"},{"line_number":272,"context_line":"\tif errors.As(err, \u0026netlink.LinkNotFoundError{}) {"},{"line_number":273,"context_line":"\t\t// CNI requires that DEL calls return success if the interface in"},{"line_number":274,"context_line":"\t\t// question does not exist."}],"source_content_type":"text/x-go","patch_set":10,"id":"338320b6_7304caab","line":271,"range":{"start_line":271,"start_character":24,"end_line":271,"end_character":35},"updated":"2025-08-11 14:29:36.000000000","message":"LinkByAlias is problematic:\n\n- Linux doesn\u0027t support lookup by alias, so this will fallback to dumping all links and doing the lookup in userspace.\n- This may fail with ErrDumpInterrupted (see doc for LinkByAlias), so it\u0027s less reliable.\n- The netlink Go package has a lookupByDump flag to remember if direct lookup fails and dump is needed, but this flag is shared between LinkByAlias and LinkByName. This means that once you call LinkByAlias, subsequent LinkByName calls also use the dump fallback. I would say this is a bug in the Go package.\n\nLinux also doesn\u0027t check aliases for uniqueness.\n\nI would prefer to keep the mapping from workload ID to interface name in userspace instead, which avoids the problems above. Here is a patch how I would do this:\n\n```\ndiff --git a/metropolis/node/core/network/workloads/workloads.go b/metropolis/node/core/network/workloads/workloads.go\nindex 7436a4ec..d9eacf7b 100644\n--- a/metropolis/node/core/network/workloads/workloads.go\n+++ b/metropolis/node/core/network/workloads/workloads.go\n@@ -38,15 +38,21 @@ type Service struct {\n \tmux          sync.Mutex\n \tworkloadNets []netip.Prefix\n \tattachments  map[netip.Addr]string\n+\t// workloadToIntf maps workload name to short interface name.\n+\tworkloadToIntf map[string]string\n+\t// intfUsed is the set of allocated short interface names.\n+\tintfUsed map[string]struct{}\n \n \tk8sNodePrefix event.Value[*clusternet.Prefixes]\n }\n \n func New(k8sNodePrefix event.Value[*clusternet.Prefixes]) *Service {\n \treturn \u0026Service{\n-\t\tworkloadNets:  []netip.Prefix{},\n-\t\tattachments:   make(map[netip.Addr]string),\n-\t\tk8sNodePrefix: k8sNodePrefix,\n+\t\tworkloadNets:   []netip.Prefix{},\n+\t\tattachments:    make(map[netip.Addr]string),\n+\t\tworkloadToIntf: make(map[string]string),\n+\t\tintfUsed:       make(map[string]struct{}),\n+\t\tk8sNodePrefix:  k8sNodePrefix,\n \t}\n }\n \n@@ -89,6 +95,48 @@ func (s *Service) deallocateIPs(workloadId string) {\n \t}\n }\n \n+// allocateIntfName allocates a short interface name for the workload. This is\n+// needed because interface names are limited to 15 characters.\n+func (s *Service) allocateIntfName(workloadId string) (string, error) {\n+\ts.mux.Lock()\n+\tdefer s.mux.Unlock()\n+\tif _, ok :\u003d s.workloadToIntf[workloadId]; ok {\n+\t\treturn \"\", fmt.Errorf(\"workload %q already has an interface\", workloadId)\n+\t}\n+\tintfPrefix :\u003d \"wk\" + workloadId[:8]\n+\tintf :\u003d intfPrefix\n+\tfor i :\u003d 0; ; i++ {\n+\t\tif _, ok :\u003d s.intfUsed[intf]; !ok {\n+\t\t\tbreak\n+\t\t}\n+\t\tif i \u003e 0xffff {\n+\t\t\treturn \"\", fmt.Errorf(\"too many interface name collisions for workload %q\", workloadId)\n+\t\t}\n+\t\tintf \u003d fmt.Sprintf(\"%s-%04x\", intfPrefix, i)\n+\t}\n+\ts.workloadToIntf[workloadId] \u003d intf\n+\ts.intfUsed[intf] \u003d struct{}{}\n+\treturn intf, nil\n+}\n+\n+func (s *Service) getIntfName(workloadId string) (string, bool) {\n+\ts.mux.Lock()\n+\tdefer s.mux.Unlock()\n+\tintf, ok :\u003d s.workloadToIntf[workloadId]\n+\treturn intf, ok\n+}\n+\n+func (s *Service) deallocateIntfName(workloadId string) {\n+\ts.mux.Lock()\n+\tdefer s.mux.Unlock()\n+\tintf, ok :\u003d s.workloadToIntf[workloadId]\n+\tif !ok {\n+\t\treturn\n+\t}\n+\tdelete(s.workloadToIntf, workloadId)\n+\tdelete(s.intfUsed, intf)\n+}\n+\n func (s *Service) Run(ctx context.Context) error {\n \tl :\u003d supervisor.Logger(ctx)\n \n@@ -134,6 +182,10 @@ func (s *Service) Run(ctx context.Context) error {\n }\n \n func (s *Service) Attach(ctx context.Context, req *wlapi.AttachRequest) (*wlapi.AttachResponse, error) {\n+\tintf, err :\u003d s.allocateIntfName(req.WorkloadId)\n+\tif err !\u003d nil {\n+\t\treturn nil, status.Errorf(codes.AlreadyExists, \"cannot add interface: %v\", err)\n+\t}\n \tworkloadAddrs, err :\u003d s.allocateIPs(req.WorkloadId)\n \tif err !\u003d nil {\n \t\treturn nil, status.Errorf(codes.ResourceExhausted, \"cannot allocate IPs: %v\", err)\n@@ -141,7 +193,7 @@ func (s *Service) Attach(ctx context.Context, req *wlapi.AttachRequest) (*wlapi.\n \n \tlinkAttrs :\u003d netlink.NewLinkAttrs()\n \tlinkAttrs.Group \u003d node.LinkGroupK8sPod\n-\tlinkAttrs.Name \u003d \"wk\" + req.WorkloadId[:8]\n+\tlinkAttrs.Name \u003d intf\n \tlinkAttrs.HardwareAddr \u003d firstHopMAC\n \n \tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)\n@@ -157,24 +209,11 @@ func (s *Service) Attach(ctx context.Context, req *wlapi.AttachRequest) (*wlapi.\n \tdefer nsHandle.Close()\n \n \thostIf :\u003d netlink.Veth{LinkAttrs: linkAttrs, PeerName: req.GetNetns().IfName, PeerNamespace: netlink.NsFd(netns)}\n-\tfor i :\u003d 0; i \u003c 65535; i++ {\n-\t\terr \u003d netlink.LinkAdd(\u0026hostIf)\n-\t\tif !errors.Is(err, unix.EEXIST) {\n-\t\t\tbreak\n-\t\t}\n-\t\tif _, err :\u003d nsHandle.LinkByName(req.GetNetns().IfName); err \u003d\u003d nil {\n-\t\t\treturn nil, fmt.Errorf(\"interface %q already exists in target namespace\", req.GetNetns().IfName)\n-\t\t}\n-\t\tlinkAttrs.Name \u003d fmt.Sprintf(\"wk%s-%x\", req.WorkloadId[:8], i)\n-\t}\n-\tif err !\u003d nil {\n+\tif err :\u003d netlink.LinkAdd(\u0026hostIf); err !\u003d nil {\n \t\treturn nil, fmt.Errorf(\"unable to create veth pair: %w\", err)\n \t}\n-\t// Linux is currently unable to assign aliases on interface creation.\n+\t// Set an alias which contains the full workload ID for debugging purposes.\n \tif err :\u003d netlink.LinkSetAlias(\u0026hostIf, \"wk\"+req.WorkloadId); err !\u003d nil {\n-\t\t// Best-effort attempt to destroy interface which cannot be\n-\t\t// reidentified.\n-\t\tnetlink.LinkDel(\u0026hostIf)\n \t\treturn nil, fmt.Errorf(\"failed to assign alias: %w\", err)\n \t}\n \tif err :\u003d netlink.LinkSetUp(\u0026hostIf); err !\u003d nil {\n@@ -252,23 +291,15 @@ func (s *Service) Attach(ctx context.Context, req *wlapi.AttachRequest) (*wlapi.\n }\n \n func (s *Service) Detach(ctx context.Context, req *wlapi.DetachRequest) (*wlapi.DetachResponse, error) {\n+\tdefer s.deallocateIntfName(req.WorkloadId)\n \tdefer s.deallocateIPs(req.WorkloadId)\n-\tnetns, err :\u003d netns.GetFromPath(req.GetNetns().NetnsPath)\n-\tif errors.Is(err, os.ErrNotExist) {\n-\t\treturn \u0026wlapi.DetachResponse{}, nil\n-\t}\n-\tif err !\u003d nil {\n-\t\treturn nil, status.Errorf(codes.Unavailable, \"cannot open network namespace: %v\", err)\n-\t}\n-\tdefer netns.Close()\n \n-\tnsHandle, err :\u003d netlink.NewHandleAt(netns, unix.NETLINK_ROUTE)\n-\tif err !\u003d nil {\n-\t\treturn nil, status.Errorf(codes.Unavailable, \"unable to get ns handle: %v\", err)\n+\tintf, ok :\u003d s.getIntfName(req.WorkloadId)\n+\tif !ok {\n+\t\treturn \u0026wlapi.DetachResponse{}, nil\n \t}\n-\tdefer nsHandle.Close()\n \n-\thostIf, err :\u003d netlink.LinkByAlias(\"wk\" + req.WorkloadId)\n+\thostIf, err :\u003d netlink.LinkByName(intf)\n \tif errors.As(err, \u0026netlink.LinkNotFoundError{}) {\n \t\t// CNI requires that DEL calls return success if the interface in\n \t\t// question does not exist.\n```","commit_id":"bfac115c1a10739b40678465970471f8aaf9aef1"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":268,"context_line":"\t}"},{"line_number":269,"context_line":"\tdefer nsHandle.Close()"},{"line_number":270,"context_line":""},{"line_number":271,"context_line":"\thostIf, err :\u003d netlink.LinkByAlias(\"wk\" + req.WorkloadId)"},{"line_number":272,"context_line":"\tif errors.As(err, \u0026netlink.LinkNotFoundError{}) {"},{"line_number":273,"context_line":"\t\t// CNI requires that DEL calls return success if the interface in"},{"line_number":274,"context_line":"\t\t// question does not exist."}],"source_content_type":"text/x-go","patch_set":10,"id":"6f66c5fb_4f9902f0","line":271,"range":{"start_line":271,"start_character":24,"end_line":271,"end_character":35},"in_reply_to":"338320b6_7304caab","updated":"2025-08-11 15:01:54.000000000","message":"You\u0027re right, I just assumed that since the code was 10 years old our Kernel should have that support now. But that apparently never happened, even mainline doesn\u0027t have it.","commit_id":"bfac115c1a10739b40678465970471f8aaf9aef1"}],"metropolis/node/kubernetes/containerd/cniproxy/cniproxy.go":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":88,"context_line":"\t}"},{"line_number":89,"context_line":"}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"type Adapter struct {"},{"line_number":92,"context_line":"\tclient wlapi.WorkloadNetworkingClient"},{"line_number":93,"context_line":"}"},{"line_number":94,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"2e46e021_0c89e6f5","line":91,"range":{"start_line":91,"start_character":5,"end_line":91,"end_character":12},"updated":"2025-08-07 16:17:35.000000000","message":"This doesn\u0027t need to be exported.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":false,"context_lines":[{"line_number":88,"context_line":"\t}"},{"line_number":89,"context_line":"}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"type Adapter struct {"},{"line_number":92,"context_line":"\tclient wlapi.WorkloadNetworkingClient"},{"line_number":93,"context_line":"}"},{"line_number":94,"context_line":""}],"source_content_type":"text/x-go","patch_set":3,"id":"80d745b9_c84729fb","line":91,"range":{"start_line":91,"start_character":5,"end_line":91,"end_character":12},"in_reply_to":"2e46e021_0c89e6f5","updated":"2025-08-07 20:24:35.000000000","message":"Done","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"}],"metropolis/node/kubernetes/containerd/main.go":[{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"db95260ad47652605f5ca71893eb9dc326f60f2d","unresolved":true,"context_lines":[{"line_number":29,"context_line":"\tEphemeralVolume *localstorage.EphemeralContainerdDirectory"},{"line_number":30,"context_line":"}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"// Ensure that cniproxy is included in the build closure"},{"line_number":33,"context_line":"type _ cni.CNI"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"func (s *Service) Run(ctx context.Context) error {"}],"source_content_type":"text/x-go","patch_set":3,"id":"e37005df_b898a721","line":32,"updated":"2025-08-07 16:17:35.000000000","message":"I don\u0027t understand what you achieve with this.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"cb250cc7ee8487700e5dd0a88eb141d2a7b14394","unresolved":false,"context_lines":[{"line_number":29,"context_line":"\tEphemeralVolume *localstorage.EphemeralContainerdDirectory"},{"line_number":30,"context_line":"}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"// Ensure that cniproxy is included in the build closure"},{"line_number":33,"context_line":"type _ cni.CNI"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"func (s *Service) Run(ctx context.Context) error {"}],"source_content_type":"text/x-go","patch_set":3,"id":"798902c7_9520fd08","line":32,"in_reply_to":"5096cbfc_4a3b5955","updated":"2025-08-11 15:01:54.000000000","message":"It works right now, we\u0027ll see if it keeps working, otherwise I\u0027ll add it back again.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000038,"name":"Jan Schär","display_name":"Jan","email":"jan@monogon.tech","username":"jan","avatars":[{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/fd0e7f48847aa0e46c8f361df2d6c26b.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"117dd0d843b43718c90324f674a56406905825ef","unresolved":true,"context_lines":[{"line_number":29,"context_line":"\tEphemeralVolume *localstorage.EphemeralContainerdDirectory"},{"line_number":30,"context_line":"}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"// Ensure that cniproxy is included in the build closure"},{"line_number":33,"context_line":"type _ cni.CNI"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"func (s *Service) Run(ctx context.Context) error {"}],"source_content_type":"text/x-go","patch_set":3,"id":"5096cbfc_4a3b5955","line":32,"in_reply_to":"9c14ac86_f44cebfd","updated":"2025-08-11 14:29:36.000000000","message":"For me, it doesn\u0027t seem to be necessary for gopls. Please try removing it.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"},{"author":{"_account_id":1000001,"name":"Lorenz Brun","display_name":"Lorenz","email":"lorenz@monogon.tech","username":"lorenz","avatars":[{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/75c04f6e9881c24ee621fba80667eed8.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"55f814e986c06ea30f45839bcaa136b48f00b7ad","unresolved":true,"context_lines":[{"line_number":29,"context_line":"\tEphemeralVolume *localstorage.EphemeralContainerdDirectory"},{"line_number":30,"context_line":"}"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"// Ensure that cniproxy is included in the build closure"},{"line_number":33,"context_line":"type _ cni.CNI"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"func (s *Service) Run(ctx context.Context) error {"}],"source_content_type":"text/x-go","patch_set":3,"id":"9c14ac86_f44cebfd","line":32,"in_reply_to":"e37005df_b898a721","updated":"2025-08-07 20:24:35.000000000","message":"This allows gopls to resolve it, at least for me it did not resolve it otherwise.","commit_id":"26fd20c538d034f416664e6e4ddc16535caccf11"}]}
