Files
infix/dev/developers-guide/index.html
T

3379 lines
76 KiB
HTML

<!DOCTYPE html><html lang="en" class="no-js"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Infix Documentation">
<link rel="canonical" href="https://kernelkit.github.io/infix/dev/developers-guide/">
<link rel="prev" href="../branding/">
<link rel="next" href="../override-package/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
<title>Developer's Guide - User's Guide</title>
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="stylesheet" href="../extra.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<link href="../assets/stylesheets/glightbox.min.css" rel="stylesheet"><script src="../assets/javascripts/glightbox.min.js"></script><style id="glightbox-style">
html.glightbox-open { overflow: initial; height: 100%; }
.gslide-title { margin-top: 0px; user-select: text; }
.gslide-desc { color: #666; user-select: text; }
.gslide-image img { background: black; }
.glightbox-clean .gslide-media { -webkit-box-shadow: none; box-shadow: none; }
.gscrollbar-fixer { padding-right: 15px; }
.gdesc-inner { font-size: 0.75rem; }
body[data-md-color-scheme="slate"] .gdesc-inner { background: var(--md-default-bg-color); }
body[data-md-color-scheme="slate"] .gslide-title { color: var(--md-default-fg-color); }
body[data-md-color-scheme="slate"] .gslide-desc { color: var(--md-default-fg-color); }
</style></head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="orange">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#developers-guide" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden="">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="https://www.kernelkit.org/" title="User's Guide" class="md-header__button md-logo" aria-label="User's Guide" data-md-component="logo">
<img src="../logo-plain.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
User's Guide
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Developer's Guide
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="orange" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"></path></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="orange" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden="">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"></path></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required="">
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"></path></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard="" data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"></path></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix="">
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/kernelkit/infix/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
</div>
<div class="md-source__repository">
kernelkit/infix
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="https://www.kernelkit.org/" title="User's Guide" class="md-nav__button md-logo" aria-label="User's Guide" data-md-component="logo">
<img src="../logo-plain.png" alt="logo">
</a>
User's Guide
</label>
<div class="md-nav__source">
<a href="https://github.com/kernelkit/infix/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
</div>
<div class="md-source__repository">
kernelkit/infix
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2">
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
CLI
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
CLI
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../cli/introduction/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/configure/" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/keybindings/" class="md-nav__link">
<span class="md-ellipsis">
Keybindings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/netcalc/" class="md-nav__link">
<span class="md-ellipsis">
Network Calculator
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/tcpdump/" class="md-nav__link">
<span class="md-ellipsis">
Network Monitoring
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/quick/" class="md-nav__link">
<span class="md-ellipsis">
Quickstart Guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/text-editor/" class="md-nav__link">
<span class="md-ellipsis">
Text Editor
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli/upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrading
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../container/" class="md-nav__link">
<span class="md-ellipsis">
Docker Containers
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4">
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Networking
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Networking
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../networking/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../iface/" class="md-nav__link">
<span class="md-ellipsis">
Common Settings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../bridging/" class="md-nav__link">
<span class="md-ellipsis">
Bridging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../lag/" class="md-nav__link">
<span class="md-ellipsis">
Link Aggregation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ethernet/" class="md-nav__link">
<span class="md-ellipsis">
Ethernet Interfaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vlan/" class="md-nav__link">
<span class="md-ellipsis">
VLAN Interfaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ip/" class="md-nav__link">
<span class="md-ellipsis">
IP Addressing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../routing/" class="md-nav__link">
<span class="md-ellipsis">
Routing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../firewall/" class="md-nav__link">
<span class="md-ellipsis">
Firewall Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../qos/" class="md-nav__link">
<span class="md-ellipsis">
Quality of Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../eth-counters/" class="md-nav__link">
<span class="md-ellipsis">
RMON Counters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tunnels/" class="md-nav__link">
<span class="md-ellipsis">
Tunneling (L2/L3)
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_13">
<label class="md-nav__link" for="__nav_4_13" id="__nav_4_13_label" tabindex="0">
<span class="md-ellipsis">
VPN Tunnels
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_13">
<span class="md-nav__icon md-icon"></span>
VPN Tunnels
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../vpn/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vpn-wireguard/" class="md-nav__link">
<span class="md-ellipsis">
WireGuard
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../wifi/" class="md-nav__link">
<span class="md-ellipsis">
Wireless LAN (WiFi)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5">
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Services
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../discovery/" class="md-nav__link">
<span class="md-ellipsis">
Device Discovery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dhcp/" class="md-nav__link">
<span class="md-ellipsis">
DHCP Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ntp/" class="md-nav__link">
<span class="md-ellipsis">
NTP Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ptp/" class="md-nav__link">
<span class="md-ellipsis">
PTP (IEEE 1588/802.1AS)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6">
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
System
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
System
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../boot/" class="md-nav__link">
<span class="md-ellipsis">
Boot Procedure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../system/" class="md-nav__link">
<span class="md-ellipsis">
Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nacm/" class="md-nav__link">
<span class="md-ellipsis">
Access Control (NACM)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hardware/" class="md-nav__link">
<span class="md-ellipsis">
Hardware Info &amp; Status
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../management/" class="md-nav__link">
<span class="md-ellipsis">
Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../keystore/" class="md-nav__link">
<span class="md-ellipsis">
Keystore
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../syslog/" class="md-nav__link">
<span class="md-ellipsis">
Syslog Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../support/" class="md-nav__link">
<span class="md-ellipsis">
Support Data
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrade
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7">
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
<span class="md-ellipsis">
Scripting
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Scripting
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../scripting/" class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-sysrepocfg/" class="md-nav__link">
<span class="md-ellipsis">
Legacy Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-netconf/" class="md-nav__link">
<span class="md-ellipsis">
NETCONF Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-restconf/" class="md-nav__link">
<span class="md-ellipsis">
RESTCONF Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scripting-prod/" class="md-nav__link">
<span class="md-ellipsis">
Production Testing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" checked="">
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
<span class="md-ellipsis">
Developer's Corner
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_8">
<span class="md-nav__icon md-icon"></span>
Developer's Corner
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a href="../branding/" class="md-nav__link">
<span class="md-ellipsis">
Branding &amp; Releases
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Developer's Guide
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Developer's Guide
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix="">
<li class="md-nav__item">
<a href="#cloning" class="md-nav__link">
<span class="md-ellipsis">
Cloning
</span>
</a>
<nav class="md-nav" aria-label="Cloning">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#customer-builds" class="md-nav__link">
<span class="md-ellipsis">
Customer Builds
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building" class="md-nav__link">
<span class="md-ellipsis">
Building
</span>
</a>
<nav class="md-nav" aria-label="Building">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#test" class="md-nav__link">
<span class="md-ellipsis">
Test
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#documentation" class="md-nav__link">
<span class="md-ellipsis">
Documentation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#development" class="md-nav__link">
<span class="md-ellipsis">
Development
</span>
</a>
<nav class="md-nav" aria-label="Development">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#configuration-snippets" class="md-nav__link">
<span class="md-ellipsis">
Configuration Snippets
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#yang-model" class="md-nav__link">
<span class="md-ellipsis">
YANG Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#configuration-migration" class="md-nav__link">
<span class="md-ellipsis">
Configuration Migration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#confd" class="md-nav__link">
<span class="md-ellipsis">
confd
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#statd" class="md-nav__link">
<span class="md-ellipsis">
statd
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#upgrading-packages" class="md-nav__link">
<span class="md-ellipsis">
Upgrading Packages
</span>
</a>
<nav class="md-nav" aria-label="Upgrading Packages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildroot" class="md-nav__link">
<span class="md-ellipsis">
Buildroot
</span>
</a>
<nav class="md-nav" aria-label="Buildroot">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#repo-locally-cloned-already" class="md-nav__link">
<span class="md-ellipsis">
Repo locally cloned already
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#no-local-repo-yet" class="md-nav__link">
<span class="md-ellipsis">
No local repo yet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#continue-here" class="md-nav__link">
<span class="md-ellipsis">
Continue Here
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#linux-kernel" class="md-nav__link">
<span class="md-ellipsis">
Linux kernel
</span>
</a>
<nav class="md-nav" aria-label="Linux kernel">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#repo-locally-cloned-already_1" class="md-nav__link">
<span class="md-ellipsis">
Repo locally cloned already
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#testing" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reviewing" class="md-nav__link">
<span class="md-ellipsis">
Reviewing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../override-package/" class="md-nav__link">
<span class="md-ellipsis">
Developing with Buildroot
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../netboot/" class="md-nav__link">
<span class="md-ellipsis">
Netboot HowTo
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../testing/" class="md-nav__link">
<span class="md-ellipsis">
Regression Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../test-arch/" class="md-nav__link">
<span class="md-ellipsis">
Test System Architecture
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../virtual/" class="md-nav__link">
<span class="md-ellipsis">
Virtual Environments
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vpd/" class="md-nav__link">
<span class="md-ellipsis">
Vital Product Data (VPD)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../license/" class="md-nav__link">
<span class="md-ellipsis">
Origin &amp; Licensing
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix="">
<li class="md-nav__item">
<a href="#cloning" class="md-nav__link">
<span class="md-ellipsis">
Cloning
</span>
</a>
<nav class="md-nav" aria-label="Cloning">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#customer-builds" class="md-nav__link">
<span class="md-ellipsis">
Customer Builds
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building" class="md-nav__link">
<span class="md-ellipsis">
Building
</span>
</a>
<nav class="md-nav" aria-label="Building">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#test" class="md-nav__link">
<span class="md-ellipsis">
Test
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#documentation" class="md-nav__link">
<span class="md-ellipsis">
Documentation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#development" class="md-nav__link">
<span class="md-ellipsis">
Development
</span>
</a>
<nav class="md-nav" aria-label="Development">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#configuration-snippets" class="md-nav__link">
<span class="md-ellipsis">
Configuration Snippets
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#yang-model" class="md-nav__link">
<span class="md-ellipsis">
YANG Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#configuration-migration" class="md-nav__link">
<span class="md-ellipsis">
Configuration Migration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#confd" class="md-nav__link">
<span class="md-ellipsis">
confd
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#statd" class="md-nav__link">
<span class="md-ellipsis">
statd
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#upgrading-packages" class="md-nav__link">
<span class="md-ellipsis">
Upgrading Packages
</span>
</a>
<nav class="md-nav" aria-label="Upgrading Packages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildroot" class="md-nav__link">
<span class="md-ellipsis">
Buildroot
</span>
</a>
<nav class="md-nav" aria-label="Buildroot">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#repo-locally-cloned-already" class="md-nav__link">
<span class="md-ellipsis">
Repo locally cloned already
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#no-local-repo-yet" class="md-nav__link">
<span class="md-ellipsis">
No local repo yet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#continue-here" class="md-nav__link">
<span class="md-ellipsis">
Continue Here
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#linux-kernel" class="md-nav__link">
<span class="md-ellipsis">
Linux kernel
</span>
</a>
<nav class="md-nav" aria-label="Linux kernel">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#repo-locally-cloned-already_1" class="md-nav__link">
<span class="md-ellipsis">
Repo locally cloned already
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#testing" class="md-nav__link">
<span class="md-ellipsis">
Testing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reviewing" class="md-nav__link">
<span class="md-ellipsis">
Reviewing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation">
<ol class="md-path__list">
<li class="md-path__item">
<a href=".." class="md-path__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-path__item">
<a href="../branding/" class="md-path__link">
<span class="md-ellipsis">
Developer's Corner
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<h1 id="developers-guide">Developer's Guide<a class="headerlink" href="#developers-guide" title="Permanent link"></a></h1>
<p>Please note, by default the <code>root</code> account is disabled in Infix NETCONF
builds. Meaning, the only way to access the system is with the <code>admin</code>
account, which is created based on credentials found in the VPD area --
for Qemu devices this is emulated using <code>qemu_fw_cfg</code>.</p>
<p>For developers this can be quite frustrating to be blocked from logging
in to debug the system. The quickest way to enable root login is to
apply the <code>dev</code> configuration snippet:</p>
<div class="highlight"><pre><span></span><code>make apply-dev
</code></pre></div>
<p>See <a href="#configuration-snippets">Configuration Snippets</a> for more details.</p>
<div class="admonition tip">
<p class="admonition-title">Important</p>
<p>Please see the <a href="#contributing">Contributing</a> section, below, for
details on how to fork and clone when contributing to Infix.</p>
</div>
<h2 id="cloning">Cloning<a class="headerlink" href="#cloning" title="Permanent link"></a></h2>
<p>When <a href="https://github.com/kernelkit/infix/releases">pre-built releases</a> are not enough, for instance when you want
to add or modify some Open Source components, you can clone the Infix
tree to your PC:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>$<span class="w"> </span>mkdir<span class="w"> </span>~/Projects<span class="p">;</span><span class="w"> </span><span class="nb">cd</span><span class="w"> </span>~/Projects
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>$<span class="w"> </span>git<span class="w"> </span>clone<span class="w"> </span>https://github.com/kernelkit/infix.git
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>..
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>infix/
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>$<span class="w"> </span>git<span class="w"> </span>submodule<span class="w"> </span>update<span class="w"> </span>--init
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>..
</code></pre></div>
<h3 id="customer-builds">Customer Builds<a class="headerlink" href="#customer-builds" title="Permanent link"></a></h3>
<p>Customer builds add product specific device trees, more OSS packages,
e.g., Frr and podman, and sometimes integrates proprietary software.
What's <em>important to remember</em>, however, is that they are all made by
setting up Infix as a GIT submodule, similar to how Infix set up a GIT
submodule for Buildroot.</p>
<p>So, in addition to using the customer's specific defconfig(s), one must
also make sure to update <em>all submodules</em>, otherwise you will likely end
up with a broken build.</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>$<span class="w"> </span>...
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>$<span class="w"> </span>git<span class="w"> </span>submodule<span class="w"> </span>update<span class="w"> </span>--init<span class="w"> </span>--recursive
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span>~~~~~~~~~~~
</code></pre></div>
<p>Other caveats should be documented in the customer specific trees.</p>
<h2 id="building">Building<a class="headerlink" href="#building" title="Permanent link"></a></h2>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>For more details, see the Getting Started and System Requirements
sections of the <a href="https://buildroot.org/downloads/manual/manual.html">excellent Buildroot manual</a>.</p>
</div>
<p>Buildroot is almost stand-alone, it needs a few locally installed tools
to bootstrap itself. The most common ones are usually part of the base
install of the OS, but specific ones for building need the following.
The instructions here are for Debian/Ubuntu based systems (YMMV):</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>bc<span class="w"> </span>binutils<span class="w"> </span>build-essential<span class="w"> </span>bzip2<span class="w"> </span>cpio<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="w"> </span>diffutils<span class="w"> </span>file<span class="w"> </span>findutils<span class="w"> </span>git<span class="w"> </span>gzip<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span>libncurses-dev<span class="w"> </span>libssl-dev<span class="w"> </span>perl<span class="w"> </span>patch<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="w"> </span>python3<span class="w"> </span>rsync<span class="w"> </span>sed<span class="w"> </span>tar<span class="w"> </span>unzip<span class="w"> </span>wget<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="w"> </span>autopoint<span class="w"> </span>bison<span class="w"> </span>flex<span class="w"> </span>autoconf<span class="w"> </span>automake<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="w"> </span>mtools
</code></pre></div>
<p>To build an Infix image; select the target and then make:</p>
<div class="highlight"><pre><span></span><code>make x86_64_defconfig
make
</code></pre></div>
<p>Online help is available:</p>
<div class="highlight"><pre><span></span><code>make help
</code></pre></div>
<p>To see available defconfigs for supported targets, use:</p>
<div class="highlight"><pre><span></span><code>make list-defconfigs
</code></pre></div>
<h3 id="test">Test<a class="headerlink" href="#test" title="Permanent link"></a></h3>
<p>Working with the regression test framework, <em>Infamy</em>, a few more tools
and services are required on your system:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>jq<span class="w"> </span>graphviz<span class="w"> </span>qemu-system-x86<span class="w"> </span>qemu-system-arm<span class="w"> </span><span class="se">\</span>
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="w"> </span>ethtool<span class="w"> </span>gdb-multiarch<span class="w"> </span>tcpdump<span class="w"> </span>tshark
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>..
</code></pre></div>
<p>To be able to build the test specification you also need:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>$<span class="w"> </span>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>python3-graphviz<span class="w"> </span>ruby-asciidoctor-pdf
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>..
</code></pre></div>
<h3 id="documentation">Documentation<a class="headerlink" href="#documentation" title="Permanent link"></a></h3>
<p>The documentation is written in Markdown, with GitHub extensions, and
published using <a href="https://squidfunk.github.io/mkdocs-material/">MkDocs, material theme</a>. This means some features
require MkDocs <em>hinting</em> which may not render fully when previewing on
GitHub -- this is OK.</p>
<p>MkDocs is packaged and available to install via <code>apt</code>, but not all of
the plugins and extensions we rely on are available, so instead we do
recommend using <code>pipx</code> to install the necessary tooling:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>pipx
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>$<span class="w"> </span>pipx<span class="w"> </span>install<span class="w"> </span>mkdocs
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a>$<span class="w"> </span>pipx<span class="w"> </span>inject<span class="w"> </span>mkdocs<span class="w"> </span>mkdocs-material<span class="w"> </span>pymdown-extensions<span class="w"> </span>mkdocs-callouts<span class="w"> </span>mike<span class="w"> </span>mkdocs-to-pdf<span class="w"> </span>mkdocs-glightbox
</code></pre></div>
<p>The <code>mike</code> and <code>mkdocs-to-pdf</code> packages are used for online versioning
and PDF generation by GitHub Actions, but since every plugin is listed
in <code>mkdocs.yml</code>, anyone who wants to preview the documentation has to
install all the tooling.</p>
<div class="admonition tip">
<p class="admonition-title">Important</p>
<p>MkDocs is also required to <strong>build a WebUI image</strong>. The build bundles
the User's Guide into the image (served on-device at <code>/guide/</code>), so
<code>make</code> runs <code>mkdocs build</code> from <code>post-build.sh</code> when the <code>webui</code>
package is selected. If MkDocs is missing the build still succeeds,
but the image ships without the on-device guide. Minimal images and
any build without the <code>webui</code> package skip this step entirely.</p>
</div>
<p>Preview with:</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>$ cd ~/src/infix/
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>$ mkdocs serve
</code></pre></div>
<h2 id="development">Development<a class="headerlink" href="#development" title="Permanent link"></a></h2>
<p>Developing with Infix is the same as <a href="https://buildroot.org/downloads/manual/manual.html#_developer_guide">developing with Buildroot</a>.
When working with a package, be it locally kept sources, or when using
<a href="../override-package/"><code>local.mk</code></a>, you only want to rebuild the parts
you have modified:</p>
<div class="highlight"><pre><span></span><code>make foo-rebuild
</code></pre></div>
<p>or</p>
<div class="highlight"><pre><span></span><code>make foo-reconfigure
</code></pre></div>
<p>or, as a last resort when nothing seems to bite:</p>
<div class="highlight"><pre><span></span><code>make foo-dirclean foo-rebuild
</code></pre></div>
<p>As shown here, you can combine multiple build targets and steps in one
go, like this:</p>
<div class="highlight"><pre><span></span><code>make foo-rebuild bar-rebuild all run
</code></pre></div>
<p>This rebuilds (and installs) <code>foo</code> and <code>bar</code>, the <code>all</code> target calls
on Buildroot to finalize the target filesystem and generate the images.
The final <code>run</code> argument is explained below.</p>
<h3 id="configuration-snippets">Configuration Snippets<a class="headerlink" href="#configuration-snippets" title="Permanent link"></a></h3>
<p>Infix ships a set of Kconfig fragments in <code>configs/snippets/</code> that can
be merged into your active <code>.config</code> on demand. This avoids polluting
defconfigs with settings that are only useful during development.</p>
<p>To see what snippets are available:</p>
<div class="highlight"><pre><span></span><code>make list-snippets
</code></pre></div>
<p>To apply a single snippet to the current output directory:</p>
<div class="highlight"><pre><span></span><code>make apply-dev # enable root login
make apply-ext4 # build an ext4 rootfs (needed for boards
# whose bootloader lacks squashfs support,
# e.g. Marvell ESPRESSObin)
make apply-mirror # prefer an internal download mirror
# (BR2_PRIMARY_SITE) over upstream sites,
# see utils/mirror-sync.sh for populating it
</code></pre></div>
<p>The <code>apply-*</code> targets require an existing <code>.config</code> (i.e. you must have
already run a <code>make &lt;board&gt;_defconfig</code>). The snippet is merged using
Buildroot's <code>merge_config.sh</code>, so it behaves like <code>make menuconfig</code>:
unrelated settings are preserved, conflicting ones are overridden.</p>
<p>To apply <strong>all</strong> snippets at once and then build:</p>
<div class="highlight"><pre><span></span><code>make dev
</code></pre></div>
<p>This is the recommended one-shot command for setting up a development
build from a freshly selected defconfig.</p>
<h3 id="yang-model">YANG Model<a class="headerlink" href="#yang-model" title="Permanent link"></a></h3>
<p>When making changes to the <code>confd</code> and <code>statd</code> services, you will often
need to update the YANG models. If you are adding a new YANG module,
it's best to follow the structure of an existing one. However, before
making any changes, <strong>always discuss them with the Infix core team</strong>.
This helps avoid issues later in development and makes pull request
reviews smoother.</p>
<h3 id="configuration-migration">Configuration Migration<a class="headerlink" href="#configuration-migration" title="Permanent link"></a></h3>
<div class="admonition tip">
<p class="admonition-title">Important</p>
<p>Whenever a YANG model change makes existing <code>startup-config</code> files
incompatible — removing a node, renaming a key, restructuring a
container — you <strong>must</strong> include a migration script so that devices
upgrading in the field are not left unbootable.</p>
</div>
<p>Migration scripts live in <code>src/confd/share/migrate/&lt;version&gt;/</code> where
<code>&lt;version&gt;</code> is the confd version (defined in <code>src/confd/configure.ac</code>)
that introduces the breaking change. Each script receives the path to
the startup configuration file as its first argument and must edit it
in-place. Scripts are run in lexicographic order, so prefix them with
a number (e.g. <code>40-my-change.sh</code>).</p>
<p>See <code>src/confd/share/migrate/1.6/40-bridge-port-remove-ip.sh</code> for a
worked example, and the <a href="../upgrade/#configuration-migration">Configuration Migration</a>
section of the Upgrade documentation for the user-facing side of this
mechanism.</p>
<h3 id="confd"><code>confd</code><a class="headerlink" href="#confd" title="Permanent link"></a></h3>
<p>The Infix <code>src/confd/</code> is the engine of the system. Currently it is a
plugin for <code>systemd-plugind</code> and contains XPath subscriptions to all the
supported YANG models.</p>
<p>There are essentially two ways of adding support for a new YANG model:</p>
<ul>
<li>The <a href="https://netopeer.liberouter.org/doc/sysrepo/master/html/dev_guide.html">sysrepo way</a>, or</li>
<li>The Infix way, using libsrx (the <code>lydx_*()</code> functions)</li>
</ul>
<p>The former is well documented in sysrepo, and the latter is best taught
by example, e.g., <code>src/confd/src/infix-dhcp.c</code>. Essentially libsrx is a
way of traversing the libyang tree instead of fetching changes by XPath.</p>
<p>When working with <code>confd</code> you likely want to enable full debug mode,
this is how you do it:</p>
<ol>
<li>Open the file <code>package/confd/confd.conf</code></li>
<li>Uncomment the first line <code>set DEBUG=1</code></li>
<li>Change the following line to add <code>-v3</code> at the end<div class="highlight"><pre><span></span><code>[S12345] sysrepo-plugind -f -p /run/confd.pid -n -- Configuration daemon
</code></pre></div>
</li>
</ol>
<p>to:</p>
<div class="highlight"><pre><span></span><code>[S12345] sysrepo-plugind -f -p /run/confd.pid -n -v3 -- Configuration daemon
</code></pre></div>
<p>Now you can rebuild <code>confd</code>, just as described above, and restart Infix:</p>
<div class="highlight"><pre><span></span><code>make confd-rebuild all run
</code></pre></div>
<h3 id="statd"><code>statd</code><a class="headerlink" href="#statd" title="Permanent link"></a></h3>
<p>The Infix status daemon, <code>src/statd</code>, is responsible for populating the
sysrepo <code>operational</code> datastore. Like <code>confd</code>, it uses XPath subscriptions,
but unlike <code>confd</code>, it relies entirely on <code>yanger</code>, a Python script that
gathers data from local linux services and feeds it into sysrepo.</p>
<p>To apply changes, rebuild the image:</p>
<div class="highlight"><pre><span></span><code>make statd-rebuild all
</code></pre></div>
<p>Rebuilding the image and testing on target for every change during
development process can be tedious. Instead, <code>yanger</code> allows remote
execution, running the script directly on the host system (test
container):</p>
<div class="highlight"><pre><span></span><code>infamy0:test # ../src/statd/python/yanger/yanger -x "../utils/ixll -A ssh d3a" ieee802-dot1ab-lldp
</code></pre></div>
<p><code>ixll</code> is a utility script that lets you run network commands using an
<strong>interface name</strong> instead of a hostname. It makes operations like
<code>ssh</code>, <code>scp</code>, and network discovery easier.</p>
<p>Normally, <code>yanger</code> runs commands <strong>locally</strong> to retrieve data
(e.g., <code>lldpcli</code> when handling <code>ieee802-dot1ab-lldp</code>). However, when
executed with <code>-x "../utils/ixll -A ssh d3a"</code> it redirects these
commands to a remote system connected to the local <code>d3a</code> interface via
SSH. This setup is used for running <code>yanger</code> in an
<a href="../testing/#interactive-usage">interactive test environment</a>. The yanger
script runs on the <code>host</code> system, but key commands are executed on the
<code>target</code> system.</p>
<p>For debugging or testing, you can capture system command output and
replay it later without needing a live system.</p>
<p>To capture:</p>
<div class="highlight"><pre><span></span><code>infamy0:test # ../src/statd/python/yanger/yanger -c /tmp/capture ieee802-dot1ab-lldp
</code></pre></div>
<p>To replay:</p>
<div class="highlight"><pre><span></span><code>infamy0:test # ../src/statd/python/yanger/yanger -r /tmp/capture ieee802-dot1ab-lldp
</code></pre></div>
<p>This is especially useful when working in isolated environments or debugging
issues without direct access to the DUT.</p>
<h2 id="upgrading-packages">Upgrading Packages<a class="headerlink" href="#upgrading-packages" title="Permanent link"></a></h2>
<h3 id="buildroot">Buildroot<a class="headerlink" href="#buildroot" title="Permanent link"></a></h3>
<p>The Kernelkit team maintains an internal <a href="https://github.com/kernelkit/buildroot">fork of Buildroot</a>, with
branches following the naming scheme <code>YYYY.MM.patch-kkit</code>
e.g. <code>2025.02.1-kkit</code>, which means a new branch should be created
whenever Buildroot is updated. These branches should contain <strong>only</strong>
changes to existing packages (but no new patches), modifications to
Buildroot itself or upstream backports.</p>
<p>The team tracks the latest Buildroot LTS (Long-Term Support) release and
updates. The impact of minor LTS release upgrades is expected to have a
very low impact and should be done as soon there is a patch release of a
Buildroot LTS available.</p>
<blockquote>
<p><strong>Depending on your setup, follow the appropriate steps below.</strong></p>
</blockquote>
<h4 id="repo-locally-cloned-already">Repo locally cloned already<a class="headerlink" href="#repo-locally-cloned-already" title="Permanent link"></a></h4>
<ol>
<li>
<p>Navigate to the Buildroot directory</p>
<div class="highlight"><pre><span></span><code>cd buildroot/
</code></pre></div>
</li>
<li>
<p>Pull the latest changes from KernelKit</p>
<div class="highlight"><pre><span></span><code>git pull
</code></pre></div>
</li>
<li>
<p>Fetch the latest tags from upstream</p>
<div class="highlight"><pre><span></span><code>git fetch upstream --tags
</code></pre></div>
</li>
</ol>
<h4 id="no-local-repo-yet">No local repo yet<a class="headerlink" href="#no-local-repo-yet" title="Permanent link"></a></h4>
<ol>
<li>
<p>Clone the Kernelkit Buildroot repository</p>
<div class="highlight"><pre><span></span><code>git clone git@github.com:kernelkit/buildroot.git
</code></pre></div>
</li>
<li>
<p>Add the upstream remote</p>
<div class="highlight"><pre><span></span><code>git remote add upstream https://gitlab.com/buildroot.org/buildroot.git
</code></pre></div>
</li>
<li>
<p>Checkout old KernelKit branch</p>
<div class="highlight"><pre><span></span><code>git checkout 2025.02.1-kkit
</code></pre></div>
</li>
</ol>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Below, it is <strong>not</strong> allowed to rebase the branch when bumped in Infix.</p>
</div>
<h4 id="continue-here">Continue Here<a class="headerlink" href="#continue-here" title="Permanent link"></a></h4>
<ol>
<li>
<p>Create a new branch based on the <strong>previous</strong> KernelKit Buildroot
release (e.g. <code>2025.02.1-kkit</code>) and name it according to the naming
scheme (e.g. <code>2025.02.2-kkit</code>)</p>
<div class="highlight"><pre><span></span><code>git checkout -b 2025.02.2-kkit
</code></pre></div>
</li>
<li>
<p>Rebase the new branch onto the corresponding upstream release</p>
<div class="highlight"><pre><span></span><code>git rebase 2025.02.2
</code></pre></div>
</li>
<li>
<p>Push the new branch and tags</p>
<div class="highlight"><pre><span></span><code>git push origin 2025.02.2-kkit --tags
</code></pre></div>
</li>
<li>
<p>In Infix, checkout new branch of Buildroot</p>
<div class="highlight"><pre><span></span><code>cd buildroot
git fetch
git checkout 2025.02.2-kkit
</code></pre></div>
</li>
<li>
<p>Commit and push the changes. <em>Remember to update the ChangeLog!</em></p>
</li>
<li>
<p>Create a pull request.</p>
</li>
</ol>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Remember to set the pull request label to <code>ci:main</code> to ensure full CI
coverage.</p>
</div>
<h3 id="linux-kernel">Linux kernel<a class="headerlink" href="#linux-kernel" title="Permanent link"></a></h3>
<p>The KernelKit team maintains an internal <a href="https://github.com/kernelkit/linux">fork of Linux kernel</a>,
with branches following the naming scheme <code>kkit-linux-[version].y</code>,
e.g. <code>kkit-6.12.y</code>, which means a new branch should be created whenever
the major kernel version is updated. This branch should contain <em>all</em>
kernel patches used by Infix.</p>
<p>The team tracks the latest Linux kernel LTS (Long-Term Support) release
and updates. The upgrade of LTS minor releases is expected to have low
impact and should be done as soon as a patch release of the LTS Linux
kernel is available.</p>
<h4 id="repo-locally-cloned-already_1">Repo locally cloned already<a class="headerlink" href="#repo-locally-cloned-already_1" title="Permanent link"></a></h4>
<ul>
<li>./utils/kernel-upgrade.sh /path/to/linux/tree</li>
<li>Update Changelog</li>
<li>push and create a pull request</li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Remember to set the pull request label to <code>ci:main</code> to ensure full CI
coverage.</p>
</div>
<h2 id="testing">Testing<a class="headerlink" href="#testing" title="Permanent link"></a></h2>
<p>Manual testing can be done using Qemu by calling <kbd>make run</kbd>,
see also <a href="../virtual/">Infix in Virtual Environments</a>, or on a physical
device by upgrading to the latest build or "<a href="../netboot/">netbooting</a>"
and running the image from RAM. The latter is how most board porting
work is done -- <strong>much quicker</strong> change-load-test cycles.</p>
<p>The Infix automated test suite is built around Qemu and <a href="https://github.com/wkz/qeneth">Qeneth</a>, see:</p>
<ul>
<li><a href="../testing/">Regression Testing with Infamy</a></li>
<li><a href="https://github.com/kernelkit/infix/blob/main/test/docker/README.md">Docker Image</a></li>
</ul>
<p>With any new feature added to Infix, it is essential to include relevant
test case(s). See the <a href="../testing/#test-development">Test Development</a>
section for guidance on adding test cases.</p>
<h2 id="reviewing">Reviewing<a class="headerlink" href="#reviewing" title="Permanent link"></a></h2>
<p>While reviewing a pull request, you might find yourself wanting to play
around with a VM running that <em>exact</em> version. For such occasions,
<a href="https://github.com/kernelkit/infix/blob/main/utils/gh-dl-artifact.sh">gh-dl-artifact.sh</a> is your friend in need! It employs the <a href="https://cli.github.com">GitHub
CLI (gh)</a> to locate a prebuilt image from our CI
workflow, download it, and prepare a local output directory from which
you can launch both <code>make run</code> instances, and run regression tests with
<code>make test</code> and friends.</p>
<p>For example, if you are curious about how PR 666 behaves in some
particular situation, you can use <code>gh</code> to switch to that branch, from
which <code>gh-dl-artifact.sh</code> can then download and prepare the
corresponding image for execution with our normal tooling:</p>
<div class="highlight"><pre><span></span><code>gh pr checkout 666
./utils/gh-dl-artifact.sh
cd x-artifact-a1b2c3d4-x86_64
make run
</code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>CI artifacts are built from a merge commit of the source and target
branches. Therefore, the version in the Infix banner will not match
the SHA of the commit you have checked out.</p>
</div>
<h2 id="contributing">Contributing<a class="headerlink" href="#contributing" title="Permanent link"></a></h2>
<p>Infix is built from many components, when contributing you need to set
up your own fork, create a local branch for your change, push to your
fork, and then use GitHub to create a <em>Pull Reqeuest</em>.</p>
<p>For this to work as <em>painlessly as possible</em> for everyone involved:</p>
<ol>
<li>Fork Infix to your own user or organization<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></li>
<li>Fork all the Infix submodules, e.g., <code>kernelkit/buildroot</code> to your
own user or organization as well</li>
<li>Clone your fork of Infix to your laptop/workstation</li>
<li><a href="https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow">Deactivate the Actions</a> you don't want in your fork</li>
<li>Please read the <a href="https://github.com/kernelkit/infix/blob/main/.github/CONTRIBUTING.md">Contributing Guidelines</a> as well!</li>
</ol>
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>~/Projects
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>$<span class="w"> </span>git<span class="w"> </span>clone<span class="w"> </span>https://github.com/YOUR_USER_NAME/infix.git
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>...
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>infix/
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a>$<span class="w"> </span>git<span class="w"> </span>submodule<span class="w"> </span>update<span class="w"> </span>--init
<a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a>...
</code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>When updating/synchronizing with upstream Infix changes you may have
to synchronize your forks as well. GitHub have a <code>Sync fork</code> button
in the GUI for your fork for this purpose. A cronjob on your server
of choice can do this for you with the <a href="https://cli.github.com/">GitHub CLI tool</a>.</p>
</div>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Organizations should make sure to lock the <code>main</code> (or <code>master</code>)
branch of their clones to ensure members do not accidentally merge
changes there. Keeping these branches in sync with upstream Infix
is highly recommended as a baseline and reference. For integration
of local changes another company-specific branch can be used instead.&nbsp;<a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"></a></p>
</li>
</ol>
</div>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright © 2022-2026 The KernelKit Team
</div>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<div class="md-progress" data-md-component="progress" role="progressbar"></div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["toc.follow", "navigation.path", "navigation.instant", "navigation.instant.progress", "navigation.tracking", "navigation.indexes", "search.highlight", "search.share", "content.code.copy", "content.code.annotate", "content.footnote.tooltips"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
document$.subscribe(()=>{ lightbox.reload(); });
</script></body></html>