mirror of
https://gitlab.com/netravnen/NetworkLabNotes.git
synced 2024-11-26 19:27:57 +00:00
Compare commits
9 commits
0de56ca43e
...
aede1fd8e0
Author | SHA1 | Date | |
---|---|---|---|
aede1fd8e0 | |||
netravnen | 0d53a7606b | ||
netravnen | e983d06d35 | ||
netravnen | ca797fb32c | ||
netravnen | ea035a7a5e | ||
netravnen | b121ca0cb4 | ||
netravnen | 1f6ff7af31 | ||
d047e79d63 | |||
netravnen | 0a97581157 |
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,4 +1,9 @@
|
||||||
|
## Archive formats
|
||||||
*.gz
|
*.gz
|
||||||
|
|
||||||
|
## Document formats
|
||||||
|
|
||||||
|
## LaTeX exceptions
|
||||||
*.aux
|
*.aux
|
||||||
*.ist
|
*.ist
|
||||||
*.acn
|
*.acn
|
||||||
|
@ -7,9 +12,15 @@
|
||||||
*.lof
|
*.lof
|
||||||
*.synctex(busy)
|
*.synctex(busy)
|
||||||
*.toc
|
*.toc
|
||||||
|
*.lot
|
||||||
*.out
|
*.out
|
||||||
latexmkrc
|
latexmkrc
|
||||||
|
!main.tex
|
||||||
/main.*
|
/main.*
|
||||||
/*.log
|
/*.log
|
||||||
|
|
||||||
|
# Editors
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Python
|
||||||
.venv
|
.venv
|
||||||
|
|
|
@ -226,12 +226,12 @@ The version of rip supporting ipv6. different to the standard rip in the ng vers
|
||||||
|
|
||||||
\section{Babel}
|
\section{Babel}
|
||||||
|
|
||||||
Babel is built on the principles of 1) \gls{dsdv}, 2) \gls{aodv}, and 3)
|
Babel is built on the principles of 1) \gls{dsdv}, 2) \gls{aodv}, and 3)
|
||||||
\gls{eigrp} protocols.
|
\gls{eigrp} protocols.
|
||||||
Made for hybrid networks\footnote{network contains wired and wireless links}
|
Made for hybrid networks\footnote{network contains wired and wireless links}
|
||||||
and can account for a high level of instability on wireless links.
|
and can account for a high level of instability on wireless links.
|
||||||
|
|
||||||
Babel has been reported to be running stable in unstable wireless networks with
|
Babel has been reported to be running stable in unstable wireless networks with
|
||||||
a level of reliability and fast convergence.
|
a level of reliability and fast convergence.
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
@ -239,24 +239,24 @@ a level of reliability and fast convergence.
|
||||||
\item Uses distributed Bellman-Ford algorithm,
|
\item Uses distributed Bellman-Ford algorithm,
|
||||||
\item \rfc{6126} in 45 pages, \textit{(28 are normative)}
|
\item \rfc{6126} in 45 pages, \textit{(28 are normative)}
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Updates by \rfc{7298} {\scriptsize (The Babel extension
|
\item Updates by \rfc{7298} {\scriptsize (The Babel extension
|
||||||
mechanism)}, and
|
mechanism)}, and
|
||||||
\item \rfc{7557} {\scriptsize (Babel \gls{hmac} Cryptographic
|
\item \rfc{7557} {\scriptsize (Babel \gls{hmac} Cryptographic
|
||||||
Authentication)}.
|
Authentication)}.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
\item Highly extensible protocol,\cite{BabelDoe86:online}
|
\item Highly extensible protocol,\cite{BabelDoe86:online}
|
||||||
\item Supports \gls{ip4} and \gls{ip6}.
|
\item Supports \gls{ip4} and \gls{ip6}.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
Babel on \underline{wired} networks uses by default hop-count. Can be
|
Babel on \underline{wired} networks uses by default hop-count. Can be
|
||||||
configured to include several values when computing the metrics.
|
configured to include several values when computing the metrics.
|
||||||
On \underline{wireless} networks Babel should be configured to take into
|
On \underline{wireless} networks Babel should be configured to take into
|
||||||
account factors such as link latency, packet loss, hop-count, and radio
|
account factors such as link latency, packet loss, hop-count, and radio
|
||||||
diversity.
|
diversity.
|
||||||
|
|
||||||
\subsection{Protocol support}
|
\subsection{Protocol support}
|
||||||
|
|
||||||
Currently the following projects include support for Babel:
|
Currently the following projects include support for Babel:
|
||||||
\cite{Babel-al30:online}
|
\cite{Babel-al30:online}
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
@ -312,26 +312,26 @@ Route-maps is used to target a select set of routes and either modify/add/remove
|
||||||
\begin{enumerate}[label={\alph*)}]
|
\begin{enumerate}[label={\alph*)}]
|
||||||
\item \Gls{bgp} communities,
|
\item \Gls{bgp} communities,
|
||||||
\item \Gls{ip} prefix,
|
\item \Gls{ip} prefix,
|
||||||
\item \Gls{bgp} as-path,
|
\item \Gls{bgp} as-path,
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
An simple example of using route-maps is
|
An simple example of using route-maps is
|
||||||
|
|
||||||
\begin{cisco}
|
\begin{cisco}
|
||||||
ip prefix-list 1 permit 172.16.0.0/16
|
ip prefix-list 1 permit 172.16.0.0/16
|
||||||
ip prefix-list 2 permit 192.168.1.0/24
|
ip prefix-list 2 permit 192.168.1.0/24
|
||||||
!
|
!
|
||||||
route-map RED permit 10
|
route-map RED permit 10
|
||||||
match ip address prefix-list 1
|
match ip address prefix-list 1
|
||||||
set ip next hop 10.1.1.1
|
set ip next hop 10.1.1.1
|
||||||
continue 20 ! Continues to apply rules normally only
|
continue 20 ! Continues to apply rules normally only
|
||||||
! applied to prefix-list 2. To apply to
|
! applied to prefix-list 2. To apply to
|
||||||
! prefix-list 1, too.
|
! prefix-list 1, too.
|
||||||
! Any attributes set in '20' will
|
! Any attributes set in '20' will
|
||||||
! override any set during '10'.
|
! override any set during '10'.
|
||||||
route-map RED permit 20
|
route-map RED permit 20
|
||||||
match ip address prefix-list 2
|
match ip address prefix-list 2
|
||||||
set ip next hop 10.2.2.2 ! Last rule overrides previous rules from
|
set ip next hop 10.2.2.2 ! Last rule overrides previous rules from
|
||||||
! previous '10' rule-set.
|
! previous '10' rule-set.
|
||||||
\end{cisco}
|
\end{cisco}
|
||||||
|
@ -368,4 +368,35 @@ Problems by running \textit{Full Mesh} is the formula of \[ iBGPsessions = n*(n-
|
||||||
\item a \gls{ttl} of 1 is the default\footnote{Multi-hop \gls{ebgp} can thou be configured and therefore increase the max-\gls{ttl} value},
|
\item a \gls{ttl} of 1 is the default\footnote{Multi-hop \gls{ebgp} can thou be configured and therefore increase the max-\gls{ttl} value},
|
||||||
\item distance is set to 20 compared to 200 for \gls{ibgp} routes,
|
\item distance is set to 20 compared to 200 for \gls{ibgp} routes,
|
||||||
\item Next hop does \textit{not} change for \gls{ebgp} routes advertised to \gls{ibgp} neighbours \textit{by-default}\footnote{Often times it is necessary to tell a router to set itself as the next-hop before advertising to \gls{ibgp} neighbours}.
|
\item Next hop does \textit{not} change for \gls{ebgp} routes advertised to \gls{ibgp} neighbours \textit{by-default}\footnote{Often times it is necessary to tell a router to set itself as the next-hop before advertising to \gls{ibgp} neighbours}.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
|
\subsection[bgpzombies]{Border Gateway Protocol Zombies}
|
||||||
|
|
||||||
|
\gls{bgp} zombies\cite{ietf-idr-bgp-sendholdtimer-00} can occuer for a multitude of reasons. Depending on the implementation. Examples are
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Overloaded control plane
|
||||||
|
\item Unable to send out update/keepalives due to full out queues
|
||||||
|
\item Stuck TCP session the \gls{bgp} daemon is unaware of (e.g. tcp window size changed to 0)
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
The consequence of \gls{bgp} sessions not being able to close properly. Can sometimes result in zombie routes. Where the router originating the route. Due to having one or more stuck sessions. Are unable to send out WITHDRAW messages. Thereby other routers think the route is still active. And does not withdraw the route from their own \gls{rib}. Ending up with a \gls{rib} containing STALL routes.
|
||||||
|
|
||||||
|
One workaround to get rid of zombie routes is to completely reset your routers \gls{rib}. This can be done by example rebooting network edge routers\cite{Navigati54:online}.
|
||||||
|
|
||||||
|
As of writing (Nov 2023) the following known public implementations have implemented the draft,
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item FRRouting\cite{bgpdimpl26:online}
|
||||||
|
\item neo-bgp\cite{Whatdoes40:online} (bgp.tools)
|
||||||
|
\item OpenBGPD\cite{Rebgpdse40:online}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
As of writing (Nov 2023) the following known public implementations are working on implementing the draft,
|
||||||
|
|
||||||
|
\begin{enumerate}
|
||||||
|
\item BIRD \url{https://gitlab.nic.cz/labs/bird/}\\
|
||||||
|
branch BGP_SendHoldTimer
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
It is unknown when commercial vendors will implement the current internet draft. This will most likely not happen until the draft has been adopted as an official RFC.
|
|
@ -7,33 +7,69 @@
|
||||||
|
|
||||||
\section{Kernel Upgrades}
|
\section{Kernel Upgrades}
|
||||||
|
|
||||||
|
LIST KERNELS ON /boot PARTITION
|
||||||
|
|
||||||
\begin{txt}
|
\begin{txt}
|
||||||
# LIST KERNELS ON /boot PARTITION
|
dpkg --list | grep linux-image
|
||||||
|
dpkg --list | grep linux-headers
|
||||||
dpkg --list | grep linux-image
|
|
||||||
dpkg --list | grep linux-headers
|
|
||||||
\end{txt}
|
\end{txt}
|
||||||
|
|
||||||
\begin{txt}
|
REMOVE SELECTED KERNEL VERSIONS FROM BOOT PARTITION
|
||||||
# REMOVE SELECTED KERNEL VERSIONS FROM BOOT PARTITION
|
|
||||||
|
|
||||||
sudo apt-get purge linux-image-4.4.0-{75,78,79}
|
|
||||||
sudo apt-get purge linux-image-extra-4.4.0-{75,78,79}
|
|
||||||
sudo apt-get purge linux-headers-4.4.0-{75,78,79}
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
sudo apt autoremove [-f]
|
|
||||||
\end{txt}
|
|
||||||
|
|
||||||
\begin{txt}
|
\begin{txt}
|
||||||
# My one-liner to remove old kernels (this also frees up disk space)
|
sudo apt-get purge linux-image-4.4.0-{75,78,79}
|
||||||
# https://askubuntu.com/a/254585
|
sudo apt-get purge linux-image-extra-4.4.0-{75,78,79}
|
||||||
|
sudo apt-get purge linux-headers-4.4.0-{75,78,79}
|
||||||
dpkg --list | grep linux-image | awk '{ print \$2 }' | sort -V | sed -n '/'`uname -r`'/q;p' | xargs sudo apt-get -y purge
|
|
||||||
\end{txt}
|
\end{txt}
|
||||||
|
|
||||||
\begin{txt}
|
or alternatively
|
||||||
# Remember to update grub2 configuration
|
|
||||||
sudo update-grub2
|
\begin{txt}
|
||||||
\end{txt}
|
sudo apt autoremove [-f]
|
||||||
|
\end{txt}
|
||||||
|
|
||||||
|
My one-liner to remove old kernels (this also frees up disk space). https://askubuntu.com/a/254585
|
||||||
|
|
||||||
|
\begin{txt}
|
||||||
|
dpkg --list | grep linux-image | awk '{ print \$2 }' | sort -V | sed -n '/'`uname -r`'/q;p' | xargs sudo apt-get -y purge
|
||||||
|
\end{txt}
|
||||||
|
|
||||||
|
Remember to update grub2 configuration
|
||||||
|
|
||||||
|
\begin{txt}
|
||||||
|
sudo update-grub2
|
||||||
|
\end{txt}
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\subsection{Proxmox}
|
||||||
|
|
||||||
|
\subsubsection{Proxmox Migrations}
|
||||||
|
|
||||||
|
Move a LXC containers storage volumes to a different storage backend, both the boot disk, and additional disks. 1400 is here the example Container ID. And ''tank'' the target storage backend. We need to stop the container before we are allowed to migrate the storage volumes of the container. We start the container back up after finishing migrating the storage volumes.
|
||||||
|
|
||||||
|
\begin{txt}
|
||||||
|
sudo pct stop 1400 && \
|
||||||
|
sudo pct move-volume 1400 rootfs tank --delete && \
|
||||||
|
sudo pct move-volume 1400 mp0 tank --delete && \
|
||||||
|
sudo pct start 1400
|
||||||
|
\end{txt}
|
||||||
|
|
||||||
|
Using Remote Migrate to migrate an LXC container to a different Proxmox Node in another Proxmox Cluster. This is an offline migration, where we turn off the Container when migration. And restarting it with the new bridge setting afterwards. If the IPs have changed. This needs to be updated manually.
|
||||||
|
|
||||||
|
\begin{txt}
|
||||||
|
sudo pct remote-migrate \
|
||||||
|
$(
|
||||||
|
sudo pct list |
|
||||||
|
grep <LOOK FOR A SPECIFIC HOSTNAME> |
|
||||||
|
grep --perl-regex --only-matching '^\d+'
|
||||||
|
) \
|
||||||
|
<TARGET CONTAINER/VM ID> \
|
||||||
|
'apitoken=PVEAPIToken=<USER>@<METHOD>!<TOKEN NAME>=<TOKEN KEY>,host=<TARGET HOSTNAME OR IP>' \
|
||||||
|
--delete 1 \
|
||||||
|
--online 0 \
|
||||||
|
--restart 1 \
|
||||||
|
--target-bridge <TARGET BRIDGE NAME> \
|
||||||
|
--target-storage <TARGET STORAGE NAME>
|
||||||
|
\end{txt}
|
||||||
|
|
||||||
|
|
26
chapter/pihole.tex
Normal file
26
chapter/pihole.tex
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
% !TeX TS-program =
|
||||||
|
% !TeX spellcheck = en_DK
|
||||||
|
% !TeX encoding = UTF-8
|
||||||
|
% !TeX root = ../main.tex
|
||||||
|
|
||||||
|
\chapter{PiHole}
|
||||||
|
|
||||||
|
\section{Whitelisting}
|
||||||
|
|
||||||
|
\subsection{Zoom Video Conferencing}
|
||||||
|
|
||||||
|
\begin{txt}
|
||||||
|
COMMENT='Zoom Video Conferencing';
|
||||||
|
|
||||||
|
pihole -w --comment "${COMMENT}" zoom.us --noreload && \
|
||||||
|
pihole -w --comment "${COMMENT}" app.zoom.us --noreload && \
|
||||||
|
pihole -w --comment "${COMMENT}" xmpp.zoom.us --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^zoom([\d\w]+)\.(cloud|\w{3})\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^\w{2}\d{1,4}\w{2}\d{1,4}\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^us\d{1,4}web\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^\w{1,4}\d{1,4}\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^\w{2}\d{1,4}\w{1,4}static\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '\.cloud\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^\w+(\d{1,2})?\.\w{2}\.zoom\.us$' --noreload && \
|
||||||
|
pihole --white-regex --comment "${COMMENT}" '^\w{2}\d{1,3}images\.zoom\.us$'
|
||||||
|
\end{txt}
|
4
main.tex
4
main.tex
|
@ -17,8 +17,7 @@
|
||||||
\def\theversion{v0.4.0}
|
\def\theversion{v0.4.0}
|
||||||
\title{Networking with switches and routers, automation and IPv4/6}
|
\title{Networking with switches and routers, automation and IPv4/6}
|
||||||
\def\thesubject{My Notes going along with learning Networking}
|
\def\thesubject{My Notes going along with learning Networking}
|
||||||
\author{"Chriztoffer Hansen" <chriztoffer@netravnen.de>\\
|
\author{"Chriztoffer" <ch@ntrv.dk>}
|
||||||
GPG: 18DD 23C5 5029 3098 DE07 052A 9DCF 2CA0 08EB D2E8}
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% %
|
% %
|
||||||
|
@ -52,6 +51,7 @@
|
||||||
\include{chapter/voip}
|
\include{chapter/voip}
|
||||||
\include{chapter/baseconf}
|
\include{chapter/baseconf}
|
||||||
\include{chapter/linux}
|
\include{chapter/linux}
|
||||||
|
\include{chapter/pihole}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% %
|
% %
|
||||||
|
|
|
@ -57,4 +57,56 @@
|
||||||
month = {},
|
month = {},
|
||||||
year = {},
|
year = {},
|
||||||
note = {(Accessed on 02/18/2018)}
|
note = {(Accessed on 02/18/2018)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@techreport{ietf-idr-bgp-sendholdtimer-00,
|
||||||
|
number = {draft-ietf-idr-bgp-sendholdtimer-00},
|
||||||
|
type = {Internet-Draft},
|
||||||
|
institution = {Internet Engineering Task Force},
|
||||||
|
publisher = {Internet Engineering Task Force},
|
||||||
|
note = {Work in Progress},
|
||||||
|
url = {https://datatracker.ietf.org/doc/draft-ietf-idr-bgp-sendholdtimer/00/},
|
||||||
|
author = {Job Snijders and Ben Cartwright-Cox},
|
||||||
|
title = {{Border Gateway Protocol 4 (BGP-4) Send Hold Timer}},
|
||||||
|
pagetotal = 8,
|
||||||
|
year = 2023,
|
||||||
|
month = may,
|
||||||
|
day = 5,
|
||||||
|
abstract = {This document defines the SendHoldTimer session attribute for the Border Gateway Protocol (BGP) Finite State Machine (FSM). Implementation of a SendHoldTimer should help overcome situations where BGP sessions are not terminated after it has become detectable for the local system that the remote system is not processing BGP messages. For robustness, this document specifies that the local system should close BGP connections and not solely rely on the remote system for session closure when BGP timers have expired. This document updates RFC4271.},
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{bgpdimpl26:online,
|
||||||
|
author = {Lamparter, D.},
|
||||||
|
title = {bgpd: implement SendHoldTimer},
|
||||||
|
howpublished = {\url{https://github.com/FRRouting/frr/pull/11225}},
|
||||||
|
month = {May},
|
||||||
|
year = {2022},
|
||||||
|
note = {(Accessed on 11/25/2023)}
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{Whatdoes40:online,
|
||||||
|
author = {Cartwright-Cox, B.},
|
||||||
|
title = {What does bgp.tools support},
|
||||||
|
howpublished = {\url{https://bgp.tools/kb/bgp-support}},
|
||||||
|
month = {August},
|
||||||
|
year = {2022},
|
||||||
|
note = {(Accessed on 11/25/2023)}
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{Rebgpdse40:online,
|
||||||
|
author = {Jeker, C.},
|
||||||
|
title = {Re: bgpd send side hold timer},
|
||||||
|
howpublished = {\url{https://marc.info/?l=openbsd-tech&m=160820754925261&w=2}},
|
||||||
|
month = {December},
|
||||||
|
year = {2022},
|
||||||
|
note = {(Accessed on 11/25/2023)}
|
||||||
|
}
|
||||||
|
|
||||||
|
@misc{Navigati54:online,
|
||||||
|
author = {Daryll Swer},
|
||||||
|
title = {Navigating a BGP Zombie Outbreak on Juniper Routers},
|
||||||
|
howpublished = {\url{https://www.daryllswer.com/navigating-a-bgp-zombie-outbreak-on-juniper-routers/}},
|
||||||
|
month = {},
|
||||||
|
year = {},
|
||||||
|
note = {(Accessed on 11/25/2023)}
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
\usepackage[T1]{fontenc}
|
\usepackage[T1]{fontenc}
|
||||||
\usepackage{fourier}
|
\usepackage{fourier}
|
||||||
\usepackage{geometry}
|
\usepackage{geometry}
|
||||||
\usepackage[toc,acronym,footnote,nomain]{glossaries} % Load the package with the acronym option
|
\usepackage[toc,acronym,nomain]{glossaries} % Load the package with the acronym option
|
||||||
\usepackage{glossaries-extra}
|
\usepackage{glossaries-extra}
|
||||||
\usepackage{graphicx}
|
\usepackage{graphicx}
|
||||||
\usepackage[unicode=false,colorlinks=true,linkcolor=darkgray,citecolor=darkgray,filecolor=darkgray,urlcolor=darkgray]{hyperref} % https://en.wikibooks.org/wiki/LaTeX/Hyperlinks
|
\usepackage[unicode=false,colorlinks=true,linkcolor=darkgray,citecolor=darkgray,filecolor=darkgray,urlcolor=darkgray]{hyperref} % https://en.wikibooks.org/wiki/LaTeX/Hyperlinks
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
\usepackage{titlepic}
|
\usepackage{titlepic}
|
||||||
\usepackage{titling} % makes available \thetitle \theauthor \thedate
|
\usepackage{titling} % makes available \thetitle \theauthor \thedate
|
||||||
\usepackage[nottoc]{tocbibind}
|
\usepackage[nottoc]{tocbibind}
|
||||||
\usepackage{transparent}
|
%\usepackage{transparent} - Returns error already defined 2023-11-25
|
||||||
\usepackage{url} % cmd \url.
|
\usepackage{url} % cmd \url.
|
||||||
\usepackage{varwidth}
|
\usepackage{varwidth}
|
||||||
\usepackage{wrapfig}
|
\usepackage{wrapfig}
|
||||||
|
|
Loading…
Reference in a new issue